@php $data = is_array($report->data) ? $report->data : json_decode($report->data, true); $header = $data['header'] ?? []; $body = $data['body'] ?? []; $footer = $data['footer'] ?? []; // HEADER / SERVICE $reportDate = $header['service_date'] ?? optional($report->service_date)->format('m/d/Y') ?? '—'; $startTime = $header['start_time'] ?? '—'; $endTime = $header['end_time'] ?? '—'; $totalHours = $header['total_hours'] ?? '—'; $technician = trim((string) ($header['technician_name'] ?? '')); $technician = $technician !== '' ? $technician : '—'; $contact = trim((string) ($header['contact_name'] ?? '')); $contact = $contact !== '' ? $contact : '—'; $serviceInterval = $header['service_interval'] ?? '—'; $inspection = $header['inspection'] ?? '—'; $cleaned = $header['cleaned'] ?? '—'; $returnVisitRaw = strtolower(trim((string) ($header['return_visit_required'] ?? ''))); $returnVisitDisplay = '—'; if ($returnVisitRaw === 'yes') { $returnVisitDisplay = 'Yes'; } elseif ($returnVisitRaw === 'no') { $returnVisitDisplay = 'No'; } // ACCOUNT $accountName = trim((string) optional($report->account)->company_name); $accountSuffix = trim((string) optional($report->account)->suffix); $accountDisplay = trim($accountName . ($accountSuffix ? ' (' . $accountSuffix . ')' : '')); // ADDRESS $primaryAddress = optional($report->account)->primaryAddress; $primaryPhone = optional($report->account)->primaryPhone; $addressLine1 = $primaryAddress->line_1 ?? '—'; $addressLine2 = $primaryAddress->line_2 ?? '—'; $city = $primaryAddress->city ?? ''; $province = $primaryAddress->state ?? ''; $postalCode = $primaryAddress->zip ?? ''; $cityProvPostal = trim(implode(' ', array_filter([$city, $province, $postalCode]))) ?: '—'; $phone = $primaryPhone->number ?? '—'; $mobilePhone = '—'; $contactMobile = null; if (!empty($header['contact_id'])) { $contactModel = \App\Models\Contact::with('phones')->find((int) $header['contact_id']); if ($contactModel) { $mobile = $contactModel->phones->first(function ($p) { $label = strtolower(trim((string) ($p->label ?? ''))); return in_array($label, ['mobile', 'cell', 'cellular']); }); if (!$mobile) { $mobile = $contactModel->phones->firstWhere('is_primary', 1); } $contactMobile = $mobile?->number; } } $mobilePhone = $contactMobile ?: '—'; // GI SERVICE DETAILS $serviceDetails = is_array($body['service_details'] ?? null) ? $body['service_details'] : []; $manufacturer = trim((string) ($serviceDetails['manufacturer'] ?? '')); $model = trim((string) ($serviceDetails['model'] ?? '')); $tankSize = trim((string) ($serviceDetails['tank_size'] ?? '')); $location = trim((string) ($serviceDetails['location'] ?? '')); $solidsPercent = trim((string) ($serviceDetails['solids_percent'] ?? '')); $greasePercent = trim((string) ($serviceDetails['grease_percent'] ?? '')); $liquidPercent = trim((string) ($serviceDetails['liquid_percent'] ?? '')); $totalLiquidCollected = trim((string) ($serviceDetails['total_liquid_collected'] ?? '')); $manufacturer = $manufacturer !== '' ? $manufacturer : '—'; $model = $model !== '' ? $model : '—'; $tankSize = $tankSize !== '' ? $tankSize : '—'; $location = $location !== '' ? $location : '—'; $solidsPercent = $solidsPercent !== '' ? $solidsPercent : '—'; $greasePercent = $greasePercent !== '' ? $greasePercent : '—'; $liquidPercent = $liquidPercent !== '' ? $liquidPercent : '—'; $totalLiquidCollected = $totalLiquidCollected !== '' ? $totalLiquidCollected : '—'; // FOOTER / NOTES $comments = trim((string) ($footer['comments'] ?? '')); $additionalNotes = trim((string) ($footer['additional_notes'] ?? '')); $scheduledCycle = trim((string) ($footer['scheduled_cycle'] ?? '')); $recommendedCycle = trim((string) ($footer['recommended_cycle'] ?? '')); $signedDate = trim((string) ($footer['signed_date'] ?? '')); $comments = $comments !== '' ? $comments : '—'; $additionalNotes = $additionalNotes !== '' ? $additionalNotes : '—'; $scheduledCycle = $scheduledCycle !== '' ? $scheduledCycle : '—'; $recommendedCycle = $recommendedCycle !== '' ? $recommendedCycle : '—'; $signedDate = $signedDate !== '' ? $signedDate : '—'; $ownerAuthorizedAgentDisplay = trim((string) ( $header['owner_name'] ?? $header['owner_authorized_agent_name'] ?? $footer['owner_authorized_agent_name'] ?? '' )); $ownerAuthorizedAgentDisplay = $ownerAuthorizedAgentDisplay !== '' ? $ownerAuthorizedAgentDisplay : '—'; // TECHNICIAN STAMP $technicianContact = null; $technicianStampUrl = null; if (!empty($header['technician_name'])) { $parts = preg_split('/\s+/', trim($header['technician_name'])); $firstName = $parts[0] ?? null; $lastName = count($parts) ? $parts[count($parts) - 1] : null; if ($firstName && $lastName) { $technicianContact = \App\Models\Contact::query() ->where('first_name', 'like', $firstName . '%') ->where('last_name', 'like', $lastName . '%') ->first(); } if ($technicianContact) { $stampMedia = $technicianContact->getFirstMedia('technician_stamp'); if ($stampMedia) { $technicianStampUrl = $stampMedia->getPath(); } } } // GI CHECKLIST $checklist = is_array($body['inspection_checklist'] ?? null) ? $body['inspection_checklist'] : []; $statusMark = function ($answer, $expected) { return strtolower((string) $answer) === strtolower((string) $expected) ? 'X' : ''; }; $defaultChecklistRows = [ ['key' => 'accessible_to_service', 'label' => 'Grease interceptor is accessible to service'], ['key' => 'condition_before', 'label' => 'Inspected condition of the grease interceptor before service'], ['key' => 'functional_prior', 'label' => 'Grease interceptor is functional prior to service'], ['key' => 'within_capacity', 'label' => 'Grease and solids do not exceed recommended capacity'], ['key' => 'no_leaks', 'label' => 'There are no leaks found in the grease interceptor'], ['key' => 'gaskets_seals', 'label' => 'Condition of the gaskets and seals'], ['key' => 'properly_cleaned', 'label' => 'Grease interceptor has been properly cleaned'], ['key' => 'flow_sufficient', 'label' => 'Rate of flow is sufficient'], ['key' => 'condition_after', 'label' => 'Condition of the grease interceptor after service'], ['key' => 'issues_reported', 'label' => 'Any issues have been reported'], ['key' => 'service_tag_updated', 'label' => 'Service tag has been issued or updated'], ['key' => 'return_visit_required', 'label' => 'Is a return visit required to complete repairs?'], ]; $savedChecklist = []; foreach ($checklist as $row) { if (!empty($row['key'])) { $savedChecklist[$row['key']] = $row; } } $rows = []; foreach ($defaultChecklistRows as $row) { $saved = $savedChecklist[$row['key']] ?? null; $rows[] = [ 'label' => $saved['label'] ?? $row['label'], 'answer' => $saved['answer'] ?? '', 'repaired' => !empty($saved['repaired']), ]; } @endphp
@include('pdfs.service-reports.partials.header', [ 'report' => $report, 'title' => 'Grease Interceptor Service Report', ])
Account
Name {{ $accountDisplay }}
Contact {{ $contact }}
Owner / Authorized Agent {{ $ownerAuthorizedAgentDisplay }}
Technician(s) {{ $technician }}
Address Line 1 {{ $addressLine1 }}
Address Line 2 {{ $addressLine2 }}
City / Prov / PC {{ $cityProvPostal }}
Phone {{ $phone }}
Mobile Phone {{ $mobilePhone }}
Service
Service Date {{ $reportDate }}
Start Time {{ $startTime }}
End Time {{ $endTime }}
Total Hours {{ $totalHours }}
Service Interval {{ $serviceInterval }}
Inspection {{ $inspection }}
Cleaned {{ $cleaned }}
Return Visit {{ $returnVisitDisplay }}
Service Details
Manufacturer {{ $manufacturer }} Model {{ $model }}
Tank Size {{ $tankSize }} Location {{ $location }}
Solids % {{ $solidsPercent }} Grease % {{ $greasePercent }}
Liquid % {{ $liquidPercent }} Total Liquid Collected {{ $totalLiquidCollected }}
Inspection Checklist
@foreach($rows as $row) @endforeach
Item Pass Fail N/A Repaired
{{ $row['label'] }} {{ $statusMark($row['answer'], 'pass') }} {{ $statusMark($row['answer'], 'fail') }} {{ $statusMark($row['answer'], 'na') }} {{ !empty($row['repaired']) ? 'X' : '' }}
@include('pdfs.service-reports.partials.footer')
@include('pdfs.service-reports.partials.header', [ 'report' => $report, 'title' => 'Grease Interceptor Service Report', ])
Additional Notes
{{ $additionalNotes !== '' ? $additionalNotes : '—' }}
@include('pdfs.service-reports.partials.footer')