@extends('layouts.app') @section('title', 'Invoice ' . $invoice->invoice_number) @section('content') @php $sv = $invoice->status instanceof \App\Enums\InvoiceStatus ? $invoice->status->value : $invoice->status; $symbol = $invoice->currency instanceof \App\Enums\Currency ? $invoice->currency->symbol() : (string) $invoice->currency; $isOverdue = $invoice->due_date->isPast() && $sv === 'unpaid'; $remaining = $invoice->remainingAmount(); $invoice->loadMissing('payments'); $payments = $invoice->payments->sortByDesc('paid_at'); $totalPaid = $payments->reduce(fn ($carry, $p) => bcadd($carry, (string) $p->amount, 2), '0'); $paidPct = bccomp((string) $invoice->amount, '0', 2) > 0 ? min(100, max(0, (int) bcmul(bcdiv($totalPaid, (string) $invoice->amount, 4), '100', 0))) : 0; $badgeClass = match($sv) { 'unpaid' => 'bg-amber-50 text-amber-700', 'partial' => 'bg-sky-50 text-sky-700', 'paid' => 'bg-emerald-50 text-emerald-700', default => 'bg-slate-100 text-slate-600', }; $badgeLabel = match($sv) { 'unpaid' => 'Unpaid', 'partial' => 'Partial Payment', 'paid' => 'Paid in Full', default => ucfirst($sv), }; $progressColor = match($sv) { 'paid' => 'bg-emerald-500', 'partial' => 'bg-sky-600', default => 'bg-slate-300', }; $paymentMethods = \App\Enums\PaymentMethod::cases(); $currencies = \App\Enums\Currency::cases(); @endphp
{{-- Flash messages --}} @if (session('success'))
{{ session('success') }}
@endif @if (session('error'))
{{ session('error') }}
@endif {{-- Page header --}}
@if($invoice->proposal_id) ← Back to Proposal @else ← Back to Invoices @endif

{{ $invoice->invoice_number }}

{{ $badgeLabel }} @if ($isOverdue) Overdue @endif
Download PDF
{{-- Two-column layout --}}
{{-- LEFT COLUMN (col-span-2): Invoice details --}}
{{-- Card 1: Amount Hero + due date + client + project --}}

Invoice Amount

{{ $symbol }} {{ number_format($invoice->amount, 2) }}

Client {{ $invoice->client->name }}
Project {{ $invoice->project->title }}
Due Date {{ $invoice->due_date->format('d M Y') }} @if ($isOverdue) ({{ $invoice->due_date->diffForHumans() }}) @endif
@if ($sv === 'paid' && $invoice->paid_at)
Paid On {{ $invoice->paid_at->format('d M Y') }}
@endif @if ($sv !== 'paid')
Remaining {{ $symbol }} {{ number_format($remaining, 2) }}
@endif
{{-- FX: Currency Conversion Box --}} @php $fxService = app(\App\Services\FxService::class); $fxRatesPhp = $fxService->getRates($invoice->currency->value); @endphp

Also shown as · Rates updated daily

@foreach($fxRatesPhp as $fxCur => $fxRate) @if($fxCur !== $invoice->currency->value) @php $fxConverted = bcmul((string) $invoice->amount, number_format((float) $fxRate, 8, '.', ''), 2); $fxSymbol = \App\Enums\Currency::from($fxCur)->symbol(); @endphp
{{ $fxCur }} {{ $fxSymbol }} {{ number_format($fxConverted, 2) }}
@endif @endforeach

Source: exchangerate-api.com · Updated daily

{{-- Card 2: Linked Proposal --}} @if ($invoice->proposal)

Linked Proposal

PROP-{{ str_pad($invoice->proposal->id, 5, '0', STR_PAD_LEFT) }} View Proposal →
@endif
{{-- RIGHT COLUMN (col-span-1): Payment Management --}}
{{-- Card A: Payment History (always visible) --}}

Payments

{{ $symbol }} {{ number_format($totalPaid, 2) }} of {{ $symbol }} {{ number_format($invoice->amount, 2) }}

{{-- Progress bar --}}

{{ (int) $paidPct }}% paid

{{-- Payment list --}} @if ($payments->isEmpty())

No payments recorded yet

@else
@foreach ($payments as $payment) @php $pmSymbol = $payment->currency instanceof \App\Enums\Currency ? $payment->currency->symbol() : (string) $payment->currency; $pmLabel = $payment->payment_method instanceof \App\Enums\PaymentMethod ? $payment->payment_method->label() : (string) $payment->payment_method; @endphp

{{ $pmSymbol }} {{ number_format($payment->amount, 2) }}

{{ $pmLabel }} · {{ \Carbon\Carbon::parse($payment->paid_at)->format('d M Y') }}

@if ($payment->notes)

{{ $payment->notes }}

@endif @if ($payment->payment_currency && $payment->payment_currency !== $payment->currency)

Paid: {{ $payment->payment_currency->symbol() }} {{ number_format($payment->payment_amount, 2) }} @ {{ number_format($payment->exchange_rate, 4) }}

@endif
@if ($sv !== 'paid')
@csrf @method('DELETE')
@endif
@endforeach
@endif
{{-- Card B: Record Payment form (hide if fully paid) --}} @if (! $invoice->isFullyPaid())

Record Payment

@csrf {{-- Validation errors --}} @if ($errors->any())
@foreach ($errors->all() as $error)

{{ $error }}

@endforeach
@endif {{-- Payment Currency --}}
{{-- Payment Amount --}}
Loading rates…
{{-- Base equivalent (hidden until amount entered) --}} {{-- Payment Method --}}
{{-- Date --}}
{{-- Notes --}}
@endif
@endsection