@php // Consolidated Invoices Report — ONE document listing every filtered // invoice as a single row in one table. NOT a batch of full invoice // PDFs. The detailed per-invoice print is served separately by // /invoice/{id}/pdf which uses `finance.partials.invoice_document`. // // View variables (from InvoiceController::listReport): // $rows collection — one lightweight row per invoice // $summary array — count / totals across $rows // $activeFilters array — human-readable filter labels // $preparer ['name','email'] — authenticated user // $renderMode 'pdf' | 'html' $isRenderPdf = ($renderMode ?? 'html') === 'pdf'; $activeFilters = $activeFilters ?? []; $preparer = $preparer ?? ['name' => null, 'email' => null]; $preparerLabel = trim((string) ($preparer['name'] ?? '')) ?: ($preparer['email'] ?? '—'); // Company info (mirrors invoice_document.blade.php lookup so branding // stays consistent between the single invoice PDF and this report). $logoSrc = null; $tryEncode = function ($path) { if (!$path || !is_file($path) || !is_readable($path)) return null; $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION)); $mime = $ext === 'jpg' || $ext === 'jpeg' ? 'image/jpeg' : ($ext === 'gif' ? 'image/gif' : ($ext === 'svg' ? 'image/svg+xml' : 'image/png')); return 'data:' . $mime . ';base64,' . base64_encode(file_get_contents($path)); }; foreach ([ public_path('images/stepup-circular-logo.png'), public_path('images/step-up-logo.png'), public_path('images/logo-round.png'), ] as $candidate) { if ($encoded = $tryEncode($candidate)) { $logoSrc = $encoded; break; } } $s = null; try { $s = \App\Models\Setting::find(1); } catch (\Throwable $e) { $s = null; } // White-label: read all identity from Company Settings + config('company.*'), // with a neutral (never brand-specific) fallback. NO whitelisting of any // particular email domain. $companyName = \App\Support\InvoiceDisplayFormatter::titleCase($s->companyName ?? '') ?: trim((string) (config('company.legal') ?: config('company.name', ''))); $companyAddress = $s->companyAddress ?? trim((string) (config('company.address.line1', '') . ' ' . config('company.address.line2', ''))); $companyPhone = $s->companyPhone ?? (string) config('company.phone', ''); $companyEmail = trim((string) ($s->companyEmail ?? config('company.email', ''))); $fmtMoney = fn ($v) => '$' . number_format((float) $v, 2); $fmtDate = fn ($d) => $d ? \Carbon\Carbon::parse($d)->format('M j, Y') : '—'; $fmtPeriod = function ($p) { if (!$p) return '—'; try { return \Carbon\Carbon::createFromFormat('Y-m', $p)->format('F Y'); } catch (\Throwable $e) { return $p; } }; $statusPill = function ($status) { $map = [ 'paid' => ['Paid', '#dcfce7', '#166534'], 'partial' => ['Partial', '#fef3c7', '#92400e'], 'overdue' => ['Overdue', '#fee2e2', '#991b1b'], 'sent' => ['Sent', '#dbeafe', '#1d4ed8'], 'draft' => ['Draft', '#f1f5f9', '#475569'], 'pending' => ['Pending', '#f1f5f9', '#475569'], 'voided' => ['Voided', '#e5e7eb', '#4b5563'], 'cancelled' => ['Cancelled', '#e5e7eb', '#4b5563'], ]; [$label, $bg, $fg] = $map[$status] ?? ['—', '#f1f5f9', '#475569']; return '' . $label . ''; }; @endphp Invoices Report @if(!$isRenderPdf) @endif
{{-- ─── Print-only Step Up tree watermark ──────────────────────── Rendered as a large faint centre-mark behind the report content on every printed page. Hidden on screen (see .report-watermark display rule) so the preview stays crisp. --}} @if($logoSrc) @endif {{-- ─── Shared Step Up header (synced with single-invoice PDF) ───── Everything except the right-column content (title + date on the list report; status badge on the single invoice) must stay identical between the two Blade files. --}}
@if($logoSrc) @endif
{{ $companyName }}
{{ $companyAddress }}
Tel: {{ $companyPhone }}  ·  Email: {{ $companyEmail }}
{{-- List-report variant: title + date + prepared by --}}
Invoices Report
Date: {{ \Carbon\Carbon::now()->format('M j, Y') }}
Prepared By: {{ $preparerLabel }}
{{-- ─── Filter summary bar ──────────────────────────────────────── --}}
Filter: @if(empty($activeFilters)) All Invoices @else @foreach($activeFilters as $f) @php $isOver = stripos($f, 'Overdue') !== false; @endphp {{ $f }} @endforeach @endif
{{-- ─── Summary cards ───────────────────────────────────────────── Outer (25% width, right-padding for the gap) never carries visible chrome — the coloured card is a nested
that owns the border, tint, and rounding. This is the Dompdf-safe way to get four equal cards separated by a gap without border-spacing inflating the total table width past 100%. --}} @php $balCls = $summary['totalBalance'] <= 0 ? 'card-balance zero' : ($summary['totalBalance'] > $summary['totalPaid'] ? 'card-balance overdue-tint' : 'card-balance'); @endphp
Total Invoices {{ (int) $summary['count'] }}
Total Amount {{ $fmtMoney($summary['totalAmount']) }}
Total Paid {{ $fmtMoney($summary['totalPaid']) }}
Total Balance {{ $fmtMoney($summary['totalBalance']) }}
{{-- ─── Main consolidated table ─────────────────────────────────── --}} {{-- Stable identifiers for this template: the `list-table` class on the data table and the hidden "Invoices Print List" marker declare a contract with /invoice/list/print callers (and the FinanceInvoiceAuthorization tests) that the list layout — not the single-invoice document — is what this endpoint serves. They live OUTSIDE the empty-state branch so an empty result set still proves the route resolved to the list template. Renaming these needs coordinated updates in the test file. --}}
@if($rows->isEmpty())
No invoices match the current filters.
Adjust the filters on the Invoices page and try again.
@else @foreach($rows as $i => $r) @endforeach
# Invoice # Student Parent Period Issue Due Location Amount Paid Balance Status
{{ $i + 1 }} {{ $r->invoiceNumber }} {{ \App\Support\InvoiceDisplayFormatter::titleCase($r->studentName) }} {{ \App\Support\InvoiceDisplayFormatter::titleCase($r->parentName) }} {{ $fmtPeriod($r->billingPeriod) }} {{ $fmtDate($r->issueDate) }} {{ $fmtDate($r->dueDate) }} {{ \App\Support\InvoiceDisplayFormatter::titleCase($r->locationName) }} {{ $fmtMoney($r->totalAmount) }} {{ $fmtMoney($r->balanceDue) }} {!! $statusPill($r->status) !!}
TOTALS  ·  {{ (int) $summary['count'] }} {{ $summary['count'] === 1 ? 'invoice' : 'invoices' }} {{ $fmtMoney($summary['totalAmount']) }} {{ $fmtMoney($summary['totalPaid']) }} {{ $fmtMoney($summary['totalBalance']) }}
@endif
{{-- ─── Shared Step Up footer (synced with single-invoice PDF) ──── --}}
Thank you for choosing {{ $companyName }}.
For questions regarding this invoice, contact {{ $companyEmail }} or {{ $companyPhone }}.