loadLangs(array('companies', 'kundenkarte@kundenkarte')); // Get parameters $anlageId = GETPOSTINT('anlage_id'); $svgContent = GETPOST('svg_content', 'restricthtml'); $format = GETPOST('format', 'alpha') ?: 'A4'; $orientation = GETPOST('orientation', 'alpha') ?: 'L'; // L=Landscape, P=Portrait // Security check if (!$user->hasRight('kundenkarte', 'read')) { accessforbidden(); } // Load Anlage data $anlage = new Anlage($db); if ($anlage->fetch($anlageId) <= 0) { die('Anlage not found'); } // Load company $societe = new Societe($db); $societe->fetch($anlage->fk_soc); // Load carriers for this anlage $carrier = new EquipmentCarrier($db); $carriers = $carrier->fetchByAnlage($anlageId); // Load equipment $equipment = new Equipment($db); $equipmentList = array(); foreach ($carriers as $c) { $eqList = $equipment->fetchByCarrier($c->id); $equipmentList = array_merge($equipmentList, $eqList); } // Load connections $connection = new EquipmentConnection($db); $connections = array(); foreach ($carriers as $c) { $connList = $connection->fetchByCarrier($c->id); $connections = array_merge($connections, $connList); } // Create PDF - Landscape A3 or A4 for schematic $pdf = pdf_getInstance(); $pdf->SetCreator('Dolibarr - Kundenkarte Schaltplan'); $pdf->SetAuthor($user->getFullName($langs)); $pdf->SetTitle('Leitungslaufplan - '.$anlage->label); // Page format if ($format == 'A3') { $pageWidth = 420; $pageHeight = 297; } else { $pageWidth = 297; $pageHeight = 210; } if ($orientation == 'P') { $tmp = $pageWidth; $pageWidth = $pageHeight; $pageHeight = $tmp; } $pdf->SetMargins(10, 10, 10); $pdf->SetAutoPageBreak(false); $pdf->AddPage($orientation, array($pageWidth, $pageHeight)); // ============================================ // DIN EN 61082 / ISO 7200 Title Block (Schriftfeld) // Position: Bottom right corner // ============================================ $titleBlockWidth = 180; $titleBlockHeight = 56; $titleBlockX = $pageWidth - $titleBlockWidth - 10; $titleBlockY = $pageHeight - $titleBlockHeight - 10; // Draw title block frame $pdf->SetDrawColor(0, 0, 0); $pdf->SetLineWidth(0.5); $pdf->Rect($titleBlockX, $titleBlockY, $titleBlockWidth, $titleBlockHeight); // Title block grid - following DIN structure // Row heights from bottom: 8, 8, 8, 8, 8, 8, 8 = 56mm total $rowHeight = 8; $rows = 7; // Column widths: 30 | 50 | 50 | 50 = 180mm $col1 = 30; // Labels $col2 = 50; // Company info $col3 = 50; // Document info $col4 = 50; // Revision info // Draw horizontal lines for ($i = 1; $i < $rows; $i++) { $y = $titleBlockY + ($i * $rowHeight); $pdf->Line($titleBlockX, $y, $titleBlockX + $titleBlockWidth, $y); } // Draw vertical lines $pdf->Line($titleBlockX + $col1, $titleBlockY, $titleBlockX + $col1, $titleBlockY + $titleBlockHeight); $pdf->Line($titleBlockX + $col1 + $col2, $titleBlockY, $titleBlockX + $col1 + $col2, $titleBlockY + $titleBlockHeight); $pdf->Line($titleBlockX + $col1 + $col2 + $col3, $titleBlockY, $titleBlockX + $col1 + $col2 + $col3, $titleBlockY + $titleBlockHeight); // Fill in title block content $pdf->SetFont('dejavusans', '', 6); $pdf->SetTextColor(0, 0, 0); // Row 1 (from top): Document title spanning full width $pdf->SetFont('dejavusans', 'B', 12); $pdf->SetXY($titleBlockX + 2, $titleBlockY + 1); $pdf->Cell($titleBlockWidth - 4, $rowHeight - 2, 'LEITUNGSLAUFPLAN', 0, 0, 'C'); // Row 2: Installation name $pdf->SetFont('dejavusans', 'B', 10); $pdf->SetXY($titleBlockX + 2, $titleBlockY + $rowHeight + 1); $pdf->Cell($titleBlockWidth - 4, $rowHeight - 2, $anlage->label, 0, 0, 'C'); // Row 3: Labels $pdf->SetFont('dejavusans', '', 6); $y = $titleBlockY + (2 * $rowHeight); $pdf->SetXY($titleBlockX + 1, $y + 1); $pdf->Cell($col1 - 2, 3, 'Erstellt', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + 1, $y + 1); $pdf->Cell($col2 - 2, 3, 'Kunde', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + 1, $y + 1); $pdf->Cell($col3 - 2, 3, 'Projekt-Nr.', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + $col3 + 1, $y + 1); $pdf->Cell($col4 - 2, 3, 'Blatt', 0, 0, 'L'); // Row 3: Values $pdf->SetFont('dejavusans', '', 8); $pdf->SetXY($titleBlockX + 1, $y + 4); $pdf->Cell($col1 - 2, 4, dol_print_date(dol_now(), 'day'), 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + 1, $y + 4); $pdf->Cell($col2 - 2, 4, dol_trunc($societe->name, 25), 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + 1, $y + 4); $pdf->Cell($col3 - 2, 4, $anlage->ref ?: '-', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + $col3 + 1, $y + 4); $pdf->Cell($col4 - 2, 4, '1 / 1', 0, 0, 'L'); // Row 4: More labels $y = $titleBlockY + (3 * $rowHeight); $pdf->SetFont('dejavusans', '', 6); $pdf->SetXY($titleBlockX + 1, $y + 1); $pdf->Cell($col1 - 2, 3, 'Bearbeiter', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + 1, $y + 1); $pdf->Cell($col2 - 2, 3, 'Adresse', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + 1, $y + 1); $pdf->Cell($col3 - 2, 3, 'Anlage', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + $col3 + 1, $y + 1); $pdf->Cell($col4 - 2, 3, 'Revision', 0, 0, 'L'); // Row 4: Values $pdf->SetFont('dejavusans', '', 8); $pdf->SetXY($titleBlockX + 1, $y + 4); $pdf->Cell($col1 - 2, 4, dol_trunc($user->getFullName($langs), 15), 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + 1, $y + 4); $address = trim($societe->address.' '.$societe->zip.' '.$societe->town); $pdf->Cell($col2 - 2, 4, dol_trunc($address, 25), 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + 1, $y + 4); $pdf->Cell($col3 - 2, 4, $anlage->type_label ?: '-', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + $col3 + 1, $y + 4); $pdf->Cell($col4 - 2, 4, 'A', 0, 0, 'L'); // Row 5: Equipment count $y = $titleBlockY + (4 * $rowHeight); $pdf->SetFont('dejavusans', '', 6); $pdf->SetXY($titleBlockX + 1, $y + 1); $pdf->Cell($col1 - 2, 3, 'Komponenten', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + 1, $y + 1); $pdf->Cell($col2 - 2, 3, 'Verbindungen', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + 1, $y + 1); $pdf->Cell($col3 - 2, 3, 'Hutschienen', 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + $col3 + 1, $y + 1); $pdf->Cell($col4 - 2, 3, 'Format', 0, 0, 'L'); $pdf->SetFont('dejavusans', '', 8); $pdf->SetXY($titleBlockX + 1, $y + 4); $pdf->Cell($col1 - 2, 4, count($equipmentList), 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + 1, $y + 4); $pdf->Cell($col2 - 2, 4, count($connections), 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + 1, $y + 4); $pdf->Cell($col3 - 2, 4, count($carriers), 0, 0, 'L'); $pdf->SetXY($titleBlockX + $col1 + $col2 + $col3 + 1, $y + 4); $pdf->Cell($col4 - 2, 4, $format.' '.$orientation, 0, 0, 'L'); // Row 6: Norm reference $y = $titleBlockY + (5 * $rowHeight); $pdf->SetFont('dejavusans', '', 6); $pdf->SetXY($titleBlockX + 1, $y + 2); $pdf->Cell($titleBlockWidth - 2, 4, 'Erstellt nach DIN EN 61082 / DIN EN 81346', 0, 0, 'C'); // Row 7: Company info $y = $titleBlockY + (6 * $rowHeight); $pdf->SetFont('dejavusans', 'B', 7); $pdf->SetXY($titleBlockX + 1, $y + 2); $pdf->Cell($titleBlockWidth - 2, 4, $mysoc->name, 0, 0, 'C'); // ============================================ // Draw the Schematic Content Area // ============================================ $schematicX = 10; $schematicY = 10; $schematicWidth = $pageWidth - 20; $schematicHeight = $titleBlockY - 15; // Draw frame around schematic area $pdf->SetDrawColor(0, 0, 0); $pdf->SetLineWidth(0.3); $pdf->Rect($schematicX, $schematicY, $schematicWidth, $schematicHeight); // If SVG content provided, embed it if (!empty($svgContent)) { // Clean SVG for TCPDF $svgContent = preg_replace('/<\?xml[^>]*\?>/', '', $svgContent); $svgContent = preg_replace('/]*>/', '', $svgContent); // Try to embed SVG try { // Scale SVG to fit in schematic area $pdf->ImageSVG('@'.$svgContent, $schematicX + 2, $schematicY + 2, $schematicWidth - 4, $schematicHeight - 4, '', '', '', 0, false); } catch (Exception $e) { // SVG embedding failed - draw placeholder $pdf->SetFont('dejavusans', 'I', 10); $pdf->SetXY($schematicX + 10, $schematicY + 10); $pdf->Cell(0, 10, 'SVG konnte nicht eingebettet werden: '.$e->getMessage(), 0, 1); } } else { // Draw schematic manually if no SVG provided drawSchematicContent($pdf, $carriers, $equipmentList, $connections, $schematicX, $schematicY, $schematicWidth, $schematicHeight); } // ============================================ // Add Wiring List on second page (Verdrahtungsliste) // ============================================ if (count($connections) > 0) { $pdf->AddPage($orientation, array($pageWidth, $pageHeight)); // Title $pdf->SetFont('dejavusans', 'B', 14); $pdf->SetXY(10, 10); $pdf->Cell(0, 8, 'VERDRAHTUNGSLISTE / KLEMMENPLAN', 0, 1, 'L'); $pdf->SetFont('dejavusans', '', 9); $pdf->SetXY(10, 18); $pdf->Cell(0, 5, $anlage->label.' - '.$societe->name, 0, 1, 'L'); // Table header $pdf->SetY(28); $pdf->SetFont('dejavusans', 'B', 8); $pdf->SetFillColor(220, 220, 220); $colWidths = array(15, 35, 25, 35, 25, 25, 30, 30); $headers = array('Nr.', 'Von (Quelle)', 'Klemme', 'Nach (Ziel)', 'Klemme', 'Typ', 'Leitung', 'Bemerkung'); $x = 10; for ($i = 0; $i < count($headers); $i++) { $pdf->SetXY($x, 28); $pdf->Cell($colWidths[$i], 6, $headers[$i], 1, 0, 'C', true); $x += $colWidths[$i]; } // Table content $pdf->SetFont('dejavusans', '', 7); $y = 34; $lineNum = 1; // Build equipment lookup $eqLookup = array(); foreach ($equipmentList as $eq) { $eqLookup[$eq->id] = $eq; } foreach ($connections as $conn) { // Skip rails/busbars in wiring list (they're separate) if ($conn->is_rail) continue; $sourceName = '-'; $sourceTerminal = $conn->source_terminal ?: '-'; $targetName = '-'; $targetTerminal = $conn->target_terminal ?: '-'; if ($conn->fk_source && isset($eqLookup[$conn->fk_source])) { $sourceName = $eqLookup[$conn->fk_source]->label ?: $eqLookup[$conn->fk_source]->type_label_short; } if ($conn->fk_target && isset($eqLookup[$conn->fk_target])) { $targetName = $eqLookup[$conn->fk_target]->label ?: $eqLookup[$conn->fk_target]->type_label_short; } // Connection type / medium $connType = $conn->connection_type ?: '-'; $medium = trim($conn->medium_type.' '.$conn->medium_spec); if (empty($medium)) $medium = '-'; $remark = $conn->output_label ?: ''; if ($y > $pageHeight - 25) { // New page $pdf->AddPage($orientation, array($pageWidth, $pageHeight)); $y = 10; // Repeat header $pdf->SetFont('dejavusans', 'B', 8); $x = 10; for ($i = 0; $i < count($headers); $i++) { $pdf->SetXY($x, $y); $pdf->Cell($colWidths[$i], 6, $headers[$i], 1, 0, 'C', true); $x += $colWidths[$i]; } $y += 6; $pdf->SetFont('dejavusans', '', 7); } $x = 10; $pdf->SetXY($x, $y); $pdf->Cell($colWidths[0], 5, $lineNum, 1, 0, 'C'); $x += $colWidths[0]; $pdf->SetXY($x, $y); $pdf->Cell($colWidths[1], 5, dol_trunc($sourceName, 18), 1, 0, 'L'); $x += $colWidths[1]; $pdf->SetXY($x, $y); $pdf->Cell($colWidths[2], 5, $sourceTerminal, 1, 0, 'C'); $x += $colWidths[2]; $pdf->SetXY($x, $y); $pdf->Cell($colWidths[3], 5, dol_trunc($targetName, 18), 1, 0, 'L'); $x += $colWidths[3]; $pdf->SetXY($x, $y); $pdf->Cell($colWidths[4], 5, $targetTerminal, 1, 0, 'C'); $x += $colWidths[4]; $pdf->SetXY($x, $y); $pdf->Cell($colWidths[5], 5, $connType, 1, 0, 'C'); $x += $colWidths[5]; $pdf->SetXY($x, $y); $pdf->Cell($colWidths[6], 5, dol_trunc($medium, 15), 1, 0, 'L'); $x += $colWidths[6]; $pdf->SetXY($x, $y); $pdf->Cell($colWidths[7], 5, dol_trunc($remark, 15), 1, 0, 'L'); $y += 5; $lineNum++; } // Add busbars section if any $busbars = array_filter($connections, function($c) { return $c->is_rail; }); if (count($busbars) > 0) { $y += 10; if ($y > $pageHeight - 40) { $pdf->AddPage($orientation, array($pageWidth, $pageHeight)); $y = 10; } $pdf->SetFont('dejavusans', 'B', 10); $pdf->SetXY(10, $y); $pdf->Cell(0, 6, 'SAMMELSCHIENEN / PHASENSCHIENEN', 0, 1, 'L'); $y += 8; $pdf->SetFont('dejavusans', 'B', 8); $bbHeaders = array('Nr.', 'Bezeichnung', 'Typ', 'Von TE', 'Bis TE', 'Phasen', 'Ausnahmen'); $bbWidths = array(15, 50, 30, 20, 20, 30, 50); $x = 10; for ($i = 0; $i < count($bbHeaders); $i++) { $pdf->SetXY($x, $y); $pdf->Cell($bbWidths[$i], 6, $bbHeaders[$i], 1, 0, 'C', true); $x += $bbWidths[$i]; } $y += 6; $pdf->SetFont('dejavusans', '', 7); $bbNum = 1; foreach ($busbars as $bb) { $x = 10; $pdf->SetXY($x, $y); $pdf->Cell($bbWidths[0], 5, $bbNum, 1, 0, 'C'); $x += $bbWidths[0]; $pdf->SetXY($x, $y); $pdf->Cell($bbWidths[1], 5, $bb->output_label ?: 'Sammelschiene '.$bbNum, 1, 0, 'L'); $x += $bbWidths[1]; $pdf->SetXY($x, $y); $pdf->Cell($bbWidths[2], 5, $bb->connection_type ?: '-', 1, 0, 'C'); $x += $bbWidths[2]; $pdf->SetXY($x, $y); $pdf->Cell($bbWidths[3], 5, $bb->rail_start_te ?: '-', 1, 0, 'C'); $x += $bbWidths[3]; $pdf->SetXY($x, $y); $pdf->Cell($bbWidths[4], 5, $bb->rail_end_te ?: '-', 1, 0, 'C'); $x += $bbWidths[4]; $pdf->SetXY($x, $y); $pdf->Cell($bbWidths[5], 5, $bb->rail_phases ?: '-', 1, 0, 'C'); $x += $bbWidths[5]; $pdf->SetXY($x, $y); $pdf->Cell($bbWidths[6], 5, $bb->excluded_te ?: '-', 1, 0, 'L'); $y += 5; $bbNum++; } } } // Output PDF $filename = 'Leitungslaufplan_'.dol_sanitizeFileName($anlage->label).'_'.date('Y-m-d').'.pdf'; $pdf->Output($filename, 'D'); /** * Draw schematic content directly in PDF * Shows only the actual equipment and connections from the database (what was drawn in the editor) */ function drawSchematicContent(&$pdf, $carriers, $equipment, $connections, $startX, $startY, $width, $height) { // Phase colors (DIN VDE compliant) $phaseColors = array( 'L1' => array(139, 69, 19), // Brown 'L2' => array(0, 0, 0), // Black 'L3' => array(128, 128, 128), // Gray 'N' => array(0, 102, 204), // Blue 'PE' => array(0, 128, 0) // Green (simplified from green-yellow) ); // Layout constants $teWidth = 10; // mm per TE $equipmentStartY = $startY + 20; $blockWidth = 8; $blockHeight = 20; // Calculate total width needed $maxTE = 0; foreach ($carriers as $carrier) { $maxTE = max($maxTE, $carrier->total_te ?: 12); } $contentWidth = min($width - 40, $maxTE * $teWidth + 40); $contentStartX = $startX + 20; // ======================================== // Draw equipment and connections // ======================================== $carrierIndex = 0; foreach ($carriers as $carrier) { $carrierY = $equipmentStartY + $carrierIndex * 50; $carrierX = $contentStartX; $totalTE = $carrier->total_te ?: 12; // Carrier label $pdf->SetFont('dejavusans', '', 6); $pdf->SetTextColor(100, 100, 100); $pdf->SetXY($carrierX - 15, $carrierY + $blockHeight / 2 - 2); $pdf->Cell(12, 4, $carrier->label ?: 'H'.($carrierIndex+1), 0, 0, 'R'); // Get equipment on this carrier $carrierEquipment = array_filter($equipment, function($eq) use ($carrier) { return $eq->fk_carrier == $carrier->id; }); // Get busbars for this carrier $carrierBusbars = array_filter($connections, function($c) use ($carrier) { return $c->is_rail && $c->fk_carrier == $carrier->id; }); // Sort equipment by position usort($carrierEquipment, function($a, $b) { return ($a->position_te ?: 1) - ($b->position_te ?: 1); }); // Draw each equipment foreach ($carrierEquipment as $eq) { $eqPosTE = $eq->position_te ?: 1; $eqWidthTE = $eq->width_te ?: 1; $eqX = $carrierX + ($eqPosTE - 1) * $teWidth; $eqWidth = $eqWidthTE * $teWidth - 2; // Equipment block $color = $eq->type_color ?: '#3498db'; list($r, $g, $b) = sscanf($color, "#%02x%02x%02x"); $pdf->SetFillColor($r ?: 52, $g ?: 152, $b ?: 219); $pdf->Rect($eqX, $carrierY, $eqWidth, $blockHeight, 'F'); // Equipment label $pdf->SetFont('dejavusans', 'B', 5); $pdf->SetTextColor(255, 255, 255); $label = $eq->type_label_short ?: $eq->label; $pdf->SetXY($eqX, $carrierY + 3); $pdf->Cell($eqWidth, 4, dol_trunc($label, 8), 0, 0, 'C'); // Second line label if ($eq->label && $eq->type_label_short) { $pdf->SetFont('dejavusans', '', 4); $pdf->SetXY($eqX, $carrierY + 8); $pdf->Cell($eqWidth, 3, dol_trunc($eq->label, 10), 0, 0, 'C'); } $pdf->SetTextColor(0, 0, 0); // Consumer label below equipment $pdf->SetFont('dejavusans', '', 5); $pdf->SetTextColor(80, 80, 80); $pdf->SetXY($eqX - 2, $carrierY + $blockHeight + 1); $consumerLabel = $eq->label ?: ''; $pdf->Cell($eqWidth + 4, 4, dol_trunc($consumerLabel, 12), 0, 0, 'C'); } // Draw busbars (Phasenschienen) for this carrier foreach ($carrierBusbars as $busbar) { $busbarStartTE = $busbar->rail_start_te ?: 1; $busbarEndTE = $busbar->rail_end_te ?: $busbarStartTE; $busbarX = $carrierX + ($busbarStartTE - 1) * $teWidth; $busbarWidth = ($busbarEndTE - $busbarStartTE + 1) * $teWidth; $busbarY = $carrierY - 5; // Busbar color $phase = $busbar->rail_phases ?: $busbar->connection_type ?: 'L1'; $color = $phaseColors[$phase] ?? array(200, 100, 50); $pdf->SetFillColor($color[0], $color[1], $color[2]); $pdf->Rect($busbarX, $busbarY, $busbarWidth, 3, 'F'); // Draw vertical taps from busbar to equipment $pdf->SetDrawColor($color[0], $color[1], $color[2]); for ($te = $busbarStartTE; $te <= $busbarEndTE; $te++) { // Check if there's equipment at this TE $hasEquipment = false; foreach ($carrierEquipment as $eq) { $eqStart = $eq->position_te ?: 1; $eqEnd = $eqStart + ($eq->width_te ?: 1) - 1; if ($te >= $eqStart && $te <= $eqEnd) { $hasEquipment = true; break; } } if ($hasEquipment) { $tapX = $carrierX + ($te - 1) * $teWidth + $teWidth / 2; $pdf->Line($tapX, $busbarY + 3, $tapX, $carrierY); } } // Busbar label $pdf->SetFont('dejavusans', 'B', 5); $pdf->SetTextColor(255, 255, 255); $pdf->SetXY($busbarX, $busbarY - 0.5); $pdf->Cell($busbarWidth, 4, $phase, 0, 0, 'C'); } // ======================================== // Draw Inputs (Anschlusspunkte) and Outputs (Abgänge) // ======================================== // Get non-rail connections for this carrier's equipment $carrierEqIds = array_map(function($eq) { return $eq->id; }, $carrierEquipment); foreach ($connections as $conn) { if ($conn->is_rail) continue; // ANSCHLUSSPUNKT (Input) - fk_source is NULL, fk_target exists if (empty($conn->fk_source) && !empty($conn->fk_target)) { // Find target equipment $targetEq = null; foreach ($carrierEquipment as $eq) { if ($eq->id == $conn->fk_target) { $targetEq = $eq; break; } } if (!$targetEq) continue; $eqPosTE = $targetEq->position_te ?: 1; $eqWidthTE = $targetEq->width_te ?: 1; $eqCenterX = $carrierX + ($eqPosTE - 1) * $teWidth + ($eqWidthTE * $teWidth) / 2; $lineStartY = $carrierY - 18; $lineEndY = $carrierY; // Phase color $phase = $conn->connection_type ?: 'L1'; $color = $phaseColors[$phase] ?? array(100, 100, 100); $pdf->SetDrawColor($color[0], $color[1], $color[2]); $pdf->SetFillColor($color[0], $color[1], $color[2]); // Vertical line from top $pdf->Line($eqCenterX, $lineStartY, $eqCenterX, $lineEndY); // Circle at top (source indicator) $pdf->Circle($eqCenterX, $lineStartY, 1.5, 0, 360, 'F'); // Phase label $pdf->SetFont('dejavusans', 'B', 7); $pdf->SetTextColor($color[0], $color[1], $color[2]); $pdf->SetXY($eqCenterX - 5, $lineStartY - 5); $pdf->Cell(10, 4, $phase, 0, 0, 'C'); // Optional label if (!empty($conn->output_label)) { $pdf->SetFont('dejavusans', '', 5); $pdf->SetTextColor(100, 100, 100); $pdf->SetXY($eqCenterX + 3, $lineStartY - 4); $pdf->Cell(20, 3, dol_trunc($conn->output_label, 12), 0, 0, 'L'); } } // ABGANG (Output) - fk_source exists, fk_target is NULL if (!empty($conn->fk_source) && empty($conn->fk_target)) { // Find source equipment $sourceEq = null; foreach ($carrierEquipment as $eq) { if ($eq->id == $conn->fk_source) { $sourceEq = $eq; break; } } if (!$sourceEq) continue; $eqPosTE = $sourceEq->position_te ?: 1; $eqWidthTE = $sourceEq->width_te ?: 1; $eqCenterX = $carrierX + ($eqPosTE - 1) * $teWidth + ($eqWidthTE * $teWidth) / 2; $lineStartY = $carrierY + $blockHeight; $lineLength = 18; $lineEndY = $lineStartY + $lineLength; // Phase color $phase = $conn->connection_type ?: 'L1N'; $color = $phaseColors[$phase] ?? $phaseColors['L1'] ?? array(139, 69, 19); $pdf->SetDrawColor($color[0], $color[1], $color[2]); $pdf->SetFillColor($color[0], $color[1], $color[2]); // Vertical line going down $pdf->Line($eqCenterX, $lineStartY, $eqCenterX, $lineEndY); // Arrow at end $pdf->Polygon(array( $eqCenterX - 1.5, $lineEndY - 2, $eqCenterX, $lineEndY, $eqCenterX + 1.5, $lineEndY - 2 ), 'F'); // Left label: Bezeichnung (rotated text not easy in TCPDF, use horizontal) if (!empty($conn->output_label)) { $pdf->SetFont('dejavusans', 'B', 5); $pdf->SetTextColor(0, 0, 0); $pdf->SetXY($eqCenterX - 15, $lineEndY + 1); $pdf->Cell(30, 3, dol_trunc($conn->output_label, 15), 0, 0, 'C'); } // Right label: Kabeltyp + Größe $cableInfo = trim(($conn->medium_type ?: '') . ' ' . ($conn->medium_spec ?: '')); if (!empty($cableInfo)) { $pdf->SetFont('dejavusans', '', 4); $pdf->SetTextColor(100, 100, 100); $pdf->SetXY($eqCenterX - 15, $lineEndY + 4); $pdf->Cell(30, 3, dol_trunc($cableInfo, 18), 0, 0, 'C'); } // Phase type $pdf->SetFont('dejavusans', 'B', 5); $pdf->SetTextColor($color[0], $color[1], $color[2]); $pdf->SetXY($eqCenterX - 5, $lineEndY + 7); $pdf->Cell(10, 3, $phase, 0, 0, 'C'); } } $carrierIndex++; } $pdf->SetTextColor(0, 0, 0); // ======================================== // Legend - show phase colors used in busbars // ======================================== $legendY = $startY + $height - 20; $pdf->SetFont('dejavusans', '', 6); $pdf->SetXY($startX + 5, $legendY); $pdf->Cell(0, 4, 'Phasenfarben nach DIN VDE:', 0, 1, 'L'); $legendX = $startX + 5; $phases = array('L1', 'L2', 'L3', 'N', 'PE'); foreach ($phases as $idx => $phase) { $color = $phaseColors[$phase]; $pdf->SetFillColor($color[0], $color[1], $color[2]); $pdf->Rect($legendX + $idx * 25, $legendY + 5, 8, 3, 'F'); $pdf->SetTextColor($color[0], $color[1], $color[2]); $pdf->SetXY($legendX + $idx * 25 + 10, $legendY + 4); $pdf->Cell(12, 4, $phase, 0, 0, 'L'); } $pdf->SetTextColor(0, 0, 0); }