Files
ladill-care/resources/views/care/bills/show.blade.php
T
isaaccladandCursor 94e53d05bf
Deploy Ladill Care / deploy (push) Successful in 1m7s
Keep consultation context on nested clinical pages and add Call again on patient queue cards.
Doctors can return to the active consultation from forms, lab, prescriptions, pathways, and bills; queue cards can re-announce called/serving tickets via the existing Queue recall bridge.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 17:48:34 +00:00

139 lines
9.6 KiB
PHP

@php $money = fn ($minor) => config('care.billing.currency').' '.number_format($minor / 100, 2); @endphp
<x-app-layout :title="$bill->invoice_number">
<x-care.consultation-return :consultation="$returnConsultation ?? null" />
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
<div>
<p class="text-xs uppercase text-slate-500">{{ $statuses[$bill->status] ?? $bill->status }}</p>
<h1 class="text-2xl font-semibold text-slate-900">{{ $bill->invoice_number }}</h1>
<p class="mt-1 text-sm text-slate-500">{{ $bill->patient->fullName() }} · {{ $bill->branch?->name }}</p>
</div>
<div class="flex gap-2">
<a href="{{ route('care.bills.print', $bill) }}" target="_blank" class="rounded-lg border border-slate-200 px-4 py-2 text-sm">Print</a>
@if ($canManage && ! in_array($bill->status, [\App\Models\Bill::STATUS_PAID, \App\Models\Bill::STATUS_VOID]))
<x-confirm-dialog
:name="'void-bill-'.$bill->id"
title="Void this bill?"
message="The invoice will be voided and can no longer be paid."
:action="route('care.bills.void', $bill)"
confirm-label="Void bill"
>
<x-slot:trigger>
<x-btn type="button" variant="danger">Void</x-btn>
</x-slot:trigger>
</x-confirm-dialog>
@endif
</div>
</div>
<div class="mt-6 grid gap-6 lg:grid-cols-3">
<section class="rounded-2xl border border-slate-200 bg-white p-6 lg:col-span-2">
<h2 class="text-sm font-semibold uppercase text-slate-500">Line items</h2>
<table class="mt-4 min-w-full text-sm">
<thead class="text-left text-xs uppercase text-slate-500"><tr><th class="py-2">Description</th><th>Qty</th><th>Unit</th><th>Total</th></tr></thead>
<tbody class="divide-y divide-slate-50">
@foreach ($bill->lineItems as $item)
<tr>
<td class="py-2">{{ $item->description }} <span class="text-slate-400">({{ $lineTypes[$item->type] ?? $item->type }})</span></td>
<td>{{ $item->quantity }}</td>
<td>{{ $money($item->unit_price_minor) }}</td>
<td>{{ $money($item->total_minor) }}</td>
</tr>
@endforeach
</tbody>
</table>
<dl class="mt-4 space-y-1 border-t border-slate-100 pt-4 text-sm">
<div class="flex justify-between"><dt class="text-slate-500">Subtotal</dt><dd>{{ $money($bill->subtotal_minor) }}</dd></div>
@if ($bill->discount_minor)<div class="flex justify-between"><dt class="text-slate-500">Discount</dt><dd>-{{ $money($bill->discount_minor) }}</dd></div>@endif
@if ($bill->tax_minor)<div class="flex justify-between"><dt class="text-slate-500">Tax</dt><dd>{{ $money($bill->tax_minor) }}</dd></div>@endif
<div class="flex justify-between font-semibold"><dt>Total</dt><dd>{{ $money($bill->total_minor) }}</dd></div>
<div class="flex justify-between text-amber-700"><dt>Balance</dt><dd>{{ $money($bill->balance_minor) }}</dd></div>
</dl>
</section>
<div class="space-y-6">
@if ($canManage && ! in_array($bill->status, [\App\Models\Bill::STATUS_PAID, \App\Models\Bill::STATUS_VOID]))
<section class="rounded-2xl border border-slate-200 bg-white p-6">
<h2 class="text-sm font-semibold uppercase text-slate-500">Add line item</h2>
<form method="POST" action="{{ route('care.bills.line-items.store', $bill) }}" class="mt-4 space-y-3">
@csrf
<select name="type" class="w-full rounded-lg border-slate-300 text-sm">@foreach ($lineTypes as $k => $v)<option value="{{ $k }}">{{ $v }}</option>@endforeach</select>
<input type="text" name="description" required placeholder="Description" class="w-full rounded-lg border-slate-300 text-sm">
<div class="grid grid-cols-2 gap-2">
<input type="number" name="quantity" value="1" min="1" class="rounded-lg border-slate-300 text-sm">
<input type="number" name="unit_price_minor" placeholder="Price (minor)" min="0" class="rounded-lg border-slate-300 text-sm">
</div>
<button type="submit" class="btn-primary w-full">Add</button>
</form>
</section>
<section class="rounded-2xl border border-slate-200 bg-white p-6">
<h2 class="text-sm font-semibold uppercase text-slate-500">Discount & tax</h2>
<form method="POST" action="{{ route('care.bills.adjustments', $bill) }}" class="mt-4 space-y-3">
@csrf
<input type="number" name="discount_minor" value="{{ $bill->discount_minor }}" min="0" placeholder="Discount (minor)" class="w-full rounded-lg border-slate-300 text-sm">
<input type="number" name="tax_minor" value="{{ $bill->tax_minor }}" min="0" placeholder="Tax (minor)" class="w-full rounded-lg border-slate-300 text-sm">
<button type="submit" class="btn-primary w-full">Update</button>
</form>
</section>
@endif
@if ($canPay && $bill->balance_minor > 0 && $bill->status !== \App\Models\Bill::STATUS_VOID)
<section class="rounded-2xl border border-slate-200 bg-white p-6">
<h2 class="text-sm font-semibold uppercase text-slate-500">Record payment</h2>
<form method="POST" action="{{ route('care.bills.payments.store', $bill) }}" class="mt-4 space-y-3">
@csrf
<input type="number" name="amount_minor" value="{{ $bill->balance_minor }}" min="1" required class="w-full rounded-lg border-slate-300 text-sm">
<select name="method" class="w-full rounded-lg border-slate-300 text-sm">@foreach ($manualPaymentMethods as $k => $v)<option value="{{ $k }}">{{ $v }}</option>@endforeach</select>
<input type="text" name="reference" placeholder="Reference" class="w-full rounded-lg border-slate-300 text-sm">
<button type="submit" class="btn-primary w-full">Record payment</button>
</form>
</section>
<section class="rounded-2xl border border-slate-200 bg-white p-6">
<h2 class="text-sm font-semibold uppercase text-slate-500">Collect online</h2>
<p class="mt-1 text-xs text-slate-500">
Card or mobile money via your connected gateway
@if ($gatewayConfigured && $gatewayProvider)
({{ $gatewayLabels[$gatewayProvider] ?? ucfirst($gatewayProvider) }})
@endif
0% Ladill fee.
</p>
@if ($gatewayConfigured)
<form method="POST" action="{{ route('care.bills.payments.gateway', $bill) }}" class="mt-4 space-y-3">
@csrf
<input type="number" name="amount_minor" value="{{ $bill->balance_minor }}" min="1" max="{{ $bill->balance_minor }}" required class="w-full rounded-lg border-slate-300 text-sm" aria-label="Amount (minor units)">
<button type="submit" class="btn-primary w-full">Open checkout</button>
</form>
@else
<p class="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800">
Connect Paystack, Flutterwave, or Hubtel in
<a href="{{ route('care.integrations') }}" class="font-medium underline">Integrations</a>
to collect online payments.
</p>
@endif
</section>
@endif
<section class="rounded-2xl border border-slate-200 bg-white p-6">
<h2 class="text-sm font-semibold uppercase text-slate-500">Payments</h2>
@forelse ($bill->payments as $payment)
@php
$methodLabel = $payment->method === \App\Models\Payment::METHOD_GATEWAY
? ($gatewayLabels[$payment->gateway_provider] ?? 'Online')
: ($paymentMethods[$payment->method] ?? $payment->method);
$statusSuffix = $payment->status === \App\Models\Payment::STATUS_PAID
? ''
: ' · '.ucfirst($payment->status);
$when = $payment->isPaid()
? ($payment->paid_at?->format('d M Y') ?? $payment->created_at->format('d M Y'))
: $payment->created_at->format('d M Y');
@endphp
<p class="mt-2 text-sm">{{ $money($payment->amount_minor) }} · {{ $methodLabel }}{{ $statusSuffix }} · {{ $when }}@if($payment->reference)<span class="text-slate-400"> · {{ $payment->reference }}</span>@endif</p>
@empty
<p class="mt-2 text-sm text-slate-400">No payments recorded.</p>
@endforelse
</section>
</div>
</div>
</x-app-layout>