Package
@php $pkgLabel = $coverage['package']['label'] ?? ($r->package_type ?? '—'); @endphp
{{ $pkgLabel }}
@if($coverage['mode'] === 'package')
KES {{ number_format($coverage['paid']) }} / {{ number_format($coverage['package']['price'] ?? 0) }}
@endif
{{-- Convert / Change Package button — visible to staff who can
manage billing. Labels differ based on current state. --}}
@if($r->status === 'active' && auth()->user()->hasAnyRole('Super Admin','Hospital Admin','Receptionist','Finance User'))
@endif
Risk {{ ucfirst($r->risk_status ?? 'normal') }}
Status {{ ucfirst($r->status) }}
Next Visit {{ $r->next_visit_date?->format('d M Y') ?? 'Not set' }}
{{-- ═══ DRAWER BUTTONS (always visible) ═══ --}}
{{-- Full cross-module patient history (OPD visits, IPD admissions,
past labs/imaging across encounters). Distinct from "View / Edit
History" above which is the ANC HPI form. --}}
{{-- ═══ ORDERS and BILLING live OUTSIDE the ANC form — they have their own forms. ═══ --}}
@include('maternity.partials._anc-orders', ['backingVisit'=>$backingVisit, 'labOrders'=>$labOrders, 'imagingRequests'=>$imagingRequests, 'prescriptions'=>$prescriptions])
@include('maternity.partials._anc-billing', ['registration'=>$r, 'coverage'=>$coverage, 'backingVisit'=>$backingVisit, 'invoice'=>$invoice, 'packageInvoice'=>$packageInvoice ?? null])
{{-- ═══ CLOSE VISIT (sticky footer). Submits the main form above. ═══ --}}
@php
// "Has content" = anything worth finalizing is on the page. The
// server-side ancVisitFinalize does the authoritative check; this
// flag just keeps the button from being offered when there's
// obviously nothing to close.
$hasDraft = $draftVisit->exists;
$hasOrders = ($labOrders->count() + $imagingRequests->count() + $prescriptions->count()) > 0;
$hasExtraItems = $invoice && $invoice->items->filter(fn($it) => ! in_array($it->source_type ?? '', ['anc_consultation','anc_package','anc_package_carry'], true))->count() > 0;
$canClose = $hasDraft || $hasOrders || $hasExtraItems;
// Compute the close gate message. Round 10 single-invoice model:
// the gate is enforced per-visit by AncPackage::canCloseVisit()
// — 50% of THIS visit's package balance must be paid before
// close. We replicate that calc here for UI feedback only.
$closeMessage = null;
if ($invoice) {
$pkgLineTotal = (float) $invoice->items->whereIn('source_type', ['anc_package','anc_package_carry'])->sum('total');
$extrasTotal = (float) $invoice->items->whereNotIn('source_type', ['anc_package','anc_package_carry'])->sum('total');
$invTotal = (float) $invoice->total_amount;
$invPaid = (float) $invoice->amount_paid;
$paidToPkg = $invTotal > 0 ? $invPaid * ($pkgLineTotal / $invTotal) : 0;
$paidToExtras = $invPaid - $paidToPkg;
$extrasUnpaid = max(0, $extrasTotal - $paidToExtras);
if ($extrasUnpaid > 0.01) {
$closeMessage = sprintf('KES %s visit extras unpaid — close will be blocked.', number_format($extrasUnpaid));
} elseif ($pkgLineTotal > 0.01 && $paidToPkg + 0.01 < $pkgLineTotal * 0.5) {
$owed = ($pkgLineTotal * 0.5) - $paidToPkg;
$closeMessage = sprintf('Package minimum not met — collect at least KES %s more (50%% of the KES %s package balance) before closing.', number_format($owed), number_format($pkgLineTotal));
}
}
@endphp
Ready to close? Runs risk evaluation and locks the visit.
@if($closeMessage)
{{ $closeMessage }}
@elseif(! $canClose)
Record vitals, a complaint, a plan, or place an order before closing.
@endif
@if(! $canClose)
@if($backingVisit && $backingVisit->status === 'in_consultation' && auth()->user()->hasAnyRole('Super Admin','Hospital Admin'))
{{-- Cancel Visit — admin-only, mirrors the routes/web.php role
gate on visits.cancel. Hidden when there's no backing
visit, when the visit is already completed/cancelled,
and for non-admin users. The handler cancels the
visit, cascades cleanup of unpaid stub records, and
preserves anything with real financial/clinical
value. The redirect_to field sends the user to the
ANC visits list afterwards — without it, back() would
return to this same URL and immediately spawn a
fresh in_consultation visit (ensureAncBackingVisit
correctly skips cancelled visits and creates a new
one), which would feel like the cancel didn't take.
Confirmation prompt because the action discards
draft work. --}}
@endif
@endif
{{-- ═══ BOOK NEXT APPOINTMENT ═══
Renders inside .enc-page so the .enc-section CSS scoping
applies (border, padding, header strip). Quick link to the
appointments form with this patient pre-selected, plus
next_visit_date pre-filled if set. The appointments/create
view reads ?patient_id=X&date=Y from the querystring. --}}
@if($r->status === 'active')
Book Next Appointment
@if($r->next_visit_date)
Suggested next visit:
{{ $r->next_visit_date->format('d M Y') }}— click to schedule a confirmed appointment for {{ $p->full_name }}.
@else
No next-visit date suggested yet — you can still book an appointment for {{ $p->full_name }} from here.
@endif
@endif
{{-- ─────────────────────────────────────────────────────────────────────
Live BMI calculation for the Vitals/Triage section.
BMI = weight(kg) / (height(m))²
Reacts to input on either Weight or Height. Marked read-only so
it's clear the value is computed; the height_cm field accepts
either a single decimal (e.g. 162.5 cm) or a whole number.
Clears BMI when either input is empty or invalid.
───────────────────────────────────────────────────────────────────── --}}
@endsection