@php /** * Helper to handle image rendering in PDF views. * Converts images (including WebP) to base64 JPEGs to ensure compatibility with DomPDF. */ $renderJobImage = function ($img) { $fullPath = public_path('storage/' . $img); if (!file_exists($fullPath)) { return ''; } $extension = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION)); try { if ($extension === 'webp' && function_exists('imagecreatefromwebp')) { $image = @imagecreatefromwebp($fullPath); if ($image) { ob_start(); imagejpeg($image, null, 70); $data = ob_get_clean(); imagedestroy($image); return 'data:image/jpeg;base64,' . base64_encode($data); } } $mime = 'image/' . ($extension === 'jpg' ? 'jpeg' : $extension); return 'data:' . $mime . ';base64,' . base64_encode(file_get_contents($fullPath)); } catch (\Exception $e) { return ''; } }; @endphp
Patrol Report
{{ $schedule->route->name }} (Duty #{{ $schedule->duty_number }})
Scheduled Date: {{ $schedule->scheduled_date->format('M d, Y') }} Scheduled Time: {{ $schedule->from_time->format('H:i') }} - {{ $schedule->to_time->format('H:i') }}
Actual Start: {{ $schedule->job_started_at ? $schedule->job_started_at->format('M d, Y H:i') : 'N/A' }} Actual End: {{ $schedule->job_ended_at ? $schedule->job_ended_at->format('M d, Y H:i') : 'N/A' }}
Total Duration: @if($schedule->job_started_at && $schedule->job_ended_at) {{ number_format($schedule->job_started_at->diffInSeconds($schedule->job_ended_at) / 3600, 2) }} hours @else - @endif Customer Ref: {{ $schedule->customer_reference ?? 'N/A' }}
Gas: ${{ number_format($pivot->gas_rate ?? 0, 2) }} Allowance: ${{ number_format($pivot->allowance ?? 0, 2) }}
Other Expense: ${{ number_format($pivot->other_expense ?? 0, 2) }} Comments: {{ $schedule->comments ?? 'N/A' }}
Total Tickets {{ $totalTickets }}
Good Tickets {{ $goodTickets }}
Bad Tickets {{ $badTickets }}
Visit Timeline
@foreach($schedule->jobSites->where('status', '!=', 'pending')->sortBy('checked_in_at') as $visit) @endforeach
Site Check In Check Out Duration Issues
{{ $visit->site->name }} {{ $visit->checked_in_at ? $visit->checked_in_at->format('H:i') : '-' }} {{ $visit->checked_out_at ? $visit->checked_out_at->format('H:i') : '-' }} @if($visit->checked_in_at && $visit->checked_out_at) {{ number_format($visit->checked_in_at->diffInSeconds($visit->checked_out_at) / 60, 2) }}m @else - @endif {{ $visit->issueTickets->count() }}
Detailed Issue Tickets
@foreach($ticketsBySite as $siteId => $tickets) @php $site = $tickets->first()->site; @endphp

{{ $site->name }}

@foreach($tickets as $ticket)
#{{ $ticket->ticket_number }} {{ strtoupper($ticket->status) }}
{{ $ticket->created_at->format('M d, Y H:i') }}
{{ $ticket->description }}
@if($ticket->images && count($ticket->images) > 0) @endif
@endforeach @endforeach