{{-- One analyte, as a card that folds open onto its own entry form. Extracted so the same markup serves both places it is needed: on its own for a test ordered singly, and inside the panel it came in with. Two copies of a clinical entry form is how one of them quietly falls behind the other. Expects: $item (LabOrderItem), and $order in scope for the routes. --}} @php $result = $item->results->firstWhere('superseded_by_id', null); $entryOpen = auth()->user()?->can('create', \App\Modules\Laboratory\Models\LabResult::class) && ! $item->status->isFinished() && ($result === null || ! $result->isVerified()); $edge = $result?->isCritical() ? 'px-testcard--critical' : (($result?->flag?->isAbnormal() ?? false) ? 'px-testcard--abnormal' : ''); /* | Where the value sits between the low and high copied onto | this result. Clamped, so a wildly out-of-range number marks | the end of the bar rather than escaping it. */ $gauge = null; if ($result?->value_numeric !== null && $result?->range_low !== null && $result?->range_high !== null) { $low = (float) $result->range_low; $high = (float) $result->range_high; if ($high > $low) { $span = $high - $low; $gauge = max(0, min(100, (((float) $result->value_numeric - ($low - $span * 0.25)) / ($span * 1.5)) * 100)); } } @endphp
{{ $item->test_name }} {{ $item->test_code }} @if ($result) {{ $result->printableValue($item->decimal_places) }} @if ($item->unit) {{ $item->unit }} @endif @if ($result->flag && $result->flag->isAbnormal()) {{ $result->flag->mark() }} {{ $result->flag->label() }} @endif @else — @endif {{-- The range, whether or not there is a value yet. A result carries the one it was read against; before that, the one it *will* be read against — which is what somebody deciding whether 14.2 is worth a second look actually needs. --}} @if ($result && $result->printableRange($item->decimal_places)) {{ $result->printableRange($item->decimal_places) }} @elseif ($expected = ($expectedRanges[$item->id] ?? null)) {{ $expected->printable($item->decimal_places) ?: "—" }} @if ($item->unit) {{ $item->unit }} @endif @else {{ __('laboratory::messages.results.no_range') }} @endif {{ $item->status->label() }}
@if ($gauge !== null)
{{ number_format((float) $result->range_low, $item->decimal_places) }} {{ number_format((float) $result->range_high, $item->decimal_places) }}
@endif @if ($result && ! $result->isVerified())

{{ __('laboratory::messages.results.unverified_notice') }}

@endif @if ($result) @can('verify', $result)
@csrf
@endcan @endif {{-- Result entry, inside the card it belongs to. A laboratory works down a list, and a modal per analyte is a modal opened forty times a morning. --}} @if ($entryOpen) {{-- Saved in place. A laboratory enters twenty results in a sitting, and a full page load between each one is twenty reloads of a screen already on the screen. --}} {{-- One line. The labels are still here for a screen reader, but a bench entering twenty numbers reads the placeholder once and never again, and a stacked label above every field turned each test into its own tall card. --}} {{-- `data-clinic-item` is what "Save all" reads: it gathers every card carrying one and posts them together under this id. The card's own Save button is untouched and still works on its own, including with no JavaScript at all. --}}
@csrf @if ($item->result_type === \App\Modules\Laboratory\Enums\ResultType::Numeric)
@elseif ($item->result_type === \App\Modules\Laboratory\Enums\ResultType::Titre)
@if ($result !== null)
{{ __('laboratory::messages.titres.record') }}
@endif @elseif ($item->result_type === \App\Modules\Laboratory\Enums\ResultType::Cutoff)
{{-- Prefilled from the test but editable: an assay kit lot carries its own cut-off, and the report must show the one this run was actually read against. --}}
@elseif ($item->result_type === \App\Modules\Laboratory\Enums\ResultType::Culture) {{-- A culture is a table of organisms, each with its own antibiotic grid, so it gets its own screen rather than a row beside a field for a single number. --}} {{-- "cv", not "c": the comment field below already owns "c{id}", and two elements answering to one id makes the label point at whichever the browser finds first. --}}
@if ($result !== null)
{{ __('laboratory::messages.cultures.record') }} @if ($result->isolates_count ?? $result->isolates()->count()) {{ $result->isolates()->count() }} @endif
@endif @elseif ($item->result_type === \App\Modules\Laboratory\Enums\ResultType::Select) {{-- A fixed list of answers the laboratory approved. Typed free text would defeat the point: the whole reason this type exists is that "Repeat With Fresh Sample" must be countable, not a sentence somebody wrote. --}} {{-- A block rather than the single-expression shorthand: the shorthand stops matching once the expression carries brackets of its own, and everything after it is then emitted as raw PHP, which takes the rest of the template with it. Note for anyone editing this file: never write a directive name after an "at" sign inside a Blade comment. Blade compiles directives before it strips comments, so the example runs. --}} @php $options = $item->test?->resultOptions ?? collect(); @endphp
@else
flag?->isAbnormal())>
@endif
@endif {{-- Amendment and version history. --}} @if ($item->results->count() > 1)
{{ __('laboratory::messages.results.history') }}: @foreach ($item->results->where('superseded_by_id', '!=', null) as $old) {{ __('laboratory::messages.results.version', ['number' => $old->version]) }} {{ $old->printableValue($item->decimal_places) }} {{ $old->verified_at?->format('Y-m-d H:i') }} @endforeach @if ($result?->amendment_reason)
{{ $result->amendment_reason }}
@endif
@endif