@extends('layouts.app') @section('title', 'Invoice | ' . ($visit->invoice?->invoice_number ?? 'New')) @section('content') @php $isAdmin = auth()->user()->hasAnyRole('Super Admin','Hospital Admin'); $isCashier = auth()->user()->hasAnyRole('Receptionist','Clinician','Nurse','Triage Nurse','Dental User','Super Admin','Hospital Admin'); $invoice = $visit->invoice; $isCompleted = in_array($visit->status, ['completed','discharged']); $invFreshBalance = 0; if ($invoice) { $invFreshTotal = $invoice->items()->sum(\DB::raw('quantity * unit_price')); $invFreshPaid = $invoice->payments()->where('status','completed')->sum('amount'); $invFreshBalance = max(0, $invFreshTotal - $invFreshPaid); } @endphp @if($invoice)

Invoice {{ $invoice->invoice_number }}

{{ $visit->patient->full_name ?? '' }} · {{ $visit->visit_number }}
Print Invoice @if(($invFreshPaid ?? 0) > 0) Print Receipt @endif
@endif
{{-- ── LEFT: Line items ───────────────────────────────────────────────── --}}
{{-- Admin banner for completed visits --}} @if($isAdmin && $isCompleted)

This visit is {{ $visit->status }} — bill is locked for regular users

As admin you can reopen it to make changes, or correct the payer type below.

@csrf
@endif {{-- ── GENERATE CLAIM BANNER (insurance/corporate invoices without a claim) ── --}} @php $isClaimWorthy = $invoice && in_array($invoice->payment_mode, ['insurance', 'corporate']); $hasExistingClaim = $isClaimWorthy ? \App\Models\InsuranceClaim::where('invoice_id', $invoice->id)->exists() : false; $canGenerateClaim = $isClaimWorthy && !$hasExistingClaim && auth()->user()->hasAnyRole('Super Admin','Hospital Admin','Finance User','Receptionist'); @endphp @if($canGenerateClaim)
No claim record for this insurance invoice. Generate one to start tracking the claim through submission → delivered → paid. The claim starts as a draft.
@csrf
@elseif($isClaimWorthy && $hasExistingClaim) @php $existingClaim = \App\Models\InsuranceClaim::where('invoice_id', $invoice->id)->latest()->first(); @endphp
Claim {{ $existingClaim->claim_number }} · Status: {{ str_replace('_',' ',$existingClaim->status) }} · Amount: KES {{ number_format((float) $existingClaim->claim_amount, 2) }} @if(($existingClaim->paid_amount ?? 0) > 0) · Paid: KES {{ number_format((float) $existingClaim->paid_amount, 2) }}@endif
View in Claims
@endif {{-- Invoice card --}}

{{ $invoice?->invoice_number ?? '' }}

{{ $visit->patient->full_name }} · {{ $visit->patient->mrn }}

{{-- Show current payer clearly --}}

Payer: @if(($invoice?->payment_mode ?? '') === 'insurance') {{ $invoice->insuranceCompany->name ?? 'Insurance' }} @else {{ ucfirst($invoice?->payment_mode ?? 'cash') }} @endif @if($isAdmin && $invoice) @endif

{{-- ── SHA member block in the payer header ────────────── Surfaces the patient's SHA identity right next to the payer label, so anyone reviewing the invoice can see it at a glance (not just on the receipt). Two sources, in priority order: (1) the most-recent SHA-tagged payment on this invoice — the values actually used for THIS bill; (2) the patient's stored SHA cover on file — useful when the invoice exists but no SHA payment has been recorded yet (e.g. visit was flagged SHA at registration). --}} @php $hdrShaCompany = \App\Models\InsuranceCompany::where('code', 'SHA')->first(); $hdrShaPay = null; $hdrShaCover = null; if ($hdrShaCompany) { // Prefer a real SHA payment on this invoice — it // reflects exactly what was captured and printed. $hdrShaPay = $invoice?->payments ?->whereNotNull('sha_number') ?->sortByDesc('created_at') ?->first(); // Fallback: patient's stored coverage. Renders // when the invoice is SHA but no payment has // been recorded yet. if (!$hdrShaPay && ($invoice?->payment_mode ?? '') === 'insurance' && $invoice?->insurance_company_id === $hdrShaCompany->id) { $hdrShaCover = \App\Models\PatientInsurance::where('patient_id', $invoice->patient_id) ->where('insurance_company_id', $hdrShaCompany->id) ->where('is_active', true) ->latest() ->first(); } } $hdrShaNumber = $hdrShaPay->sha_number ?? $hdrShaCover->member_number ?? null; $hdrShaMember = $hdrShaPay->sha_member_name ?? $hdrShaCover->principal_name ?? null; $hdrShaRel = $hdrShaPay->sha_relationship ?? $hdrShaCover->relationship ?? null; $hdrShaAuth = $hdrShaPay->sha_auth_reference ?? null; $hdrShaSource = $hdrShaPay ? 'payment' : ($hdrShaCover ? 'file' : null); @endphp @if($hdrShaNumber)
SHA Member @if($hdrShaSource === 'file') on file @endif
@if($hdrShaAuth) @endif
SHA No. {{ $hdrShaNumber }} Relationship {{ $hdrShaRel ?? '—' }}
Member {{ $hdrShaMember ?? '—' }}
Auth Ref {{ $hdrShaAuth }}
@endif
{{ ucfirst($invoice?->status ?? 'new') }}
{{-- Fix Payer Panel (admin only, hidden by default) --}} @if($isAdmin && $invoice) @endif @php $canEditItems = auth()->user()->hasAnyRole('Receptionist','Clinician','Nurse','Triage Nurse','Dental User','Hospital Admin','Super Admin'); @endphp
@foreach($invoice?->items ?? [] as $item) {{-- Qty: editable inline --}} {{-- Unit Price: editable inline --}} @endforeach
Item Category Qty Unit Price Total
{{ $item->description }} {{ $item->category }} @if($canEditItems) @else {{ $item->quantity }} @endif @if($canEditItems) @else {{ number_format($item->unit_price) }} @endif KES {{ number_format($item->total) }} @if($canEditItems)
@csrf @method('DELETE')
@endif
Total: KES {{ number_format($invoice?->total_amount ?? 0) }}
{{-- /items table scroll wrapper --}}
{{-- ── RIGHT: Payments ─────────────────────────────────────────────────── --}}
@if($invFreshBalance > 0) @if($isCashier)

Record Payment

@csrf
@php // SHA detection — same convention as the shared // _payment-section partial: identify SHA by the // canonical company code 'SHA', not by display // name, so renaming the row never breaks the // mandatory-fields trigger. $invShaCompany = \App\Models\InsuranceCompany::where('code', 'SHA')->first(); $invShaName = $invShaCompany?->name ?? 'SHA (Social Health Authority)'; // Whether the panel should be open on initial // render (admin returning to a saved SHA invoice). $invShaPreselected = ($invoice?->insuranceCompany?->name ?? null) === $invShaName && ($invoice?->payment_mode ?? '') === 'insurance'; // Prefill from the patient's existing SHA cover // (patient_insurances). Written on first SHA // capture by BillingController, refreshed on // every subsequent SHA payment. Auth reference // is intentionally not prefilled — episode-specific. $invShaCover = null; if ($invShaCompany && ($invoice?->patient_id ?? null)) { $invShaCover = \App\Models\PatientInsurance::where('patient_id', $invoice->patient_id) ->where('insurance_company_id', $invShaCompany->id) ->where('is_active', true) ->latest() ->first(); } @endphp
{{-- SHA member-identity panel for the billing page form. --}} {{-- Mirrors the inline panel in _payment-section.blade.php --}} {{-- so SHA receipts captured from either screen carry the --}} {{-- same fields. --}}
SHA Member Details (required) @if($invShaCover) ✓ From file @endif
@else

Payments are recorded by the Cashier.

Outstanding balance: KES {{ number_format($invFreshBalance) }}

@endif @else

Bill Fully Paid

No outstanding balance

@endif

Payments

@forelse($invoice?->payments ?? [] as $pay)

{{ $pay->description ?? ucfirst($pay->payment_method) }}

{{ $pay->created_at->format('d M H:i') }}

KES {{ number_format($pay->amount) }}

@empty

No payments yet.

@endforelse
@endsection @section('scripts') @endsection