@extends('layouts.app') @section('title', $prescription->reference) @php /* | The status enum reports a Bootstrap contextual name, because that is what | it was written against. Mapped here rather than changed there: the same | enum labels a badge on the listing and in the print view, and this | screen's design language is not a reason to move it. */ $statusPill = match ($prescription->status->tone()) { 'success' => 'px-pill--green', 'warning' => 'px-pill--amber', 'danger' => 'px-pill--red', 'primary', 'info' => 'px-pill--blue', default => 'px-pill--grey', }; /* | Live warnings while the prescription is a draft; for an issued one, the | warnings recorded at the moment of issue, because those are what the | prescriber actually saw and acted on. */ $shownWarnings = $prescription->isEditable() ? $warnings : []; @endphp @section('content') {{-- ── Page head ──────────────────────────────────────────────────────── --}}

{{ $patient?->name ?? '—' }}

{{ $prescription->reference }}

@can('print', $prescription) {{-- Its own tab: the prescription stays on screen behind the printout, and a target also tells the page swapper to leave this click alone — the print page is a standalone document with its own styles, not something it can put in this layout. --}} {{ __('prescriptions::messages.prescriptions.print') }} @endcan
{{-- Everything that identifies this prescription, on one line: what state it is in, whose it is, who wrote it, when, and how many times it has been printed. --}}
@if ($prescription->status->isDispensable()) @else @endif {{ $prescription->status->label() }} @if ($patient) {{ $patient->mrn }} @endif @if ($doctor?->label()) {{ $doctor->label() }} @endif @if ($prescription->issued_at) {{ __('prescriptions::messages.prescriptions.issued_at') }}: {{ $prescription->issued_at->format('Y-m-d') }} @endif @if ($prescription->print_count > 0) {{ trans_choice('prescriptions::messages.prescriptions.copies_printed', $prescription->print_count, ['count' => $prescription->print_count]) }} @endif
{{-- ── What can still be done to it ───────────────────────────────────── --}} @if ($prescription->isEditable())
{{ __('prescriptions::messages.prescriptions.draft_notice') }}
@elseif ($prescription->status->isDispensable())
{{ __('prescriptions::messages.prescriptions.issued_notice') }}
@if ($prescription->hasExpired())
{{ __('prescriptions::messages.prescriptions.expired_notice') }}
@endif @endif {{-- Allergy conflicts. Loud on purpose: this is the one thing on the screen that should stop somebody mid-click. --}} @if ($shownWarnings !== [])

{{ __('prescriptions::messages.allergy.heading') }}

{{ __('prescriptions::messages.allergy.checked_note') }}

@elseif ($prescription->allergy_warnings)

{{ __('prescriptions::messages.allergy.overridden') }}

{{ $prescription->allergy_override_reason }}

@endif
{{-- ── The prescription itself ────────────────────────────────────── --}}
@forelse ($prescription->items as $item)
{{ $item->drug_name }} @if ($item->strength){{ $item->strength }}@endif @if ($item->is_controlled) {{ __('prescriptions::messages.items.controlled') }} @endif
{{ $item->directions() }}
@if ($item->indication)
{{ __('prescriptions::messages.items.indication') }}: {{ $item->indication }}
@endif @if ($item->instructions)
{{ $item->instructions }}
@endif
@can('update', $prescription)
@endcan
@empty {{-- The one place on this page still drawing a Bootstrap empty state; the rest of the screen is px. --}}

{{ __('prescriptions::messages.items.empty') }}

{{ __('prescriptions::messages.items.empty_text') }}

@endforelse @can('update', $prescription) {{-- The prescribing form. Every data attribute here is load-bearing: Clinic.prescribing reads them to run the formulary type-ahead and to check what is being typed against the patient's allergies before it is added. The names, the hidden fields and the results list are its contract with this markup. --}}
@csrf
    @error('drug_name')
    {{ $message }}
    @enderror
    {{-- Read by Clinic.dispensing as well as stored: "2 tablets" twice daily is four a day, not two. A strength like "5 mg" counts as one, because how many tablets make up 5 mg depends on the tablet. --}}
    {{-- Picked, not typed. Nearly every prescription is one of eight, and three prescribers writing "BD", "bd" and "twice a day" is three spellings of one instruction. "Other" hands the free-text box back for the ones that are not — revealed by Clinic.frequency, because an instruction that will not fit the field ends up in a notes box nobody prints. --}}
    @error('frequency')
    {{ $message }}
    @enderror
    {{-- Worked out from the frequency and the duration, and only ever as a suggestion: see Clinic.dispensing. The note under it says the figure was calculated, because a number appearing on its own in the box a pharmacy dispenses against should not be silent. --}}
    @endcan
    {{-- Lifestyle and dietary advice. Prints with the prescription, so the patient leaves with the plan and the medicines on the same page rather than being told the plan and expected to remember. --}} @forelse ($prescription->protocols as $attached)
    {{ $attached->title }} @can('update', $prescription)
    @csrf @method('DELETE')
    @endcan
      @foreach ($attached->lines() as $line)
    • {{ $line }}
    • @endforeach
    @empty

    {{ __('prescriptions::messages.protocols.none') }}

    @endforelse @can('update', $prescription) @if ($availableProtocols->isNotEmpty())
    @csrf
    @elseif (Route::has('protocols.index'))

    {{ __('prescriptions::messages.protocols.manage') }}

    @endif @endcan
    {{-- ── What can be done about it ──────────────────────────────────── --}}
    @forelse ($allergies as $allergy)
    {{ $allergy->allergen }} {{ $allergy->severity }} @if ($allergy->reaction)
    {{ $allergy->reaction }}
    @endif
    @empty

    {{ __('prescriptions::messages.allergy.none') }}

    @endforelse
    @can('issue', $prescription) {{-- Read it before you sign it. Issuing is the moment a draft becomes something a patient collects from a pharmacy, and it used to be one click from a sidebar that shows none of what is being issued — the medicines are in the other column, and on a long list the last one added is off the bottom of the screen. The button now opens the whole prescription as it will be dispensed. Nothing is submitted until Issue is pressed inside it. --}}

    {{ __('prescriptions::messages.prescriptions.review_hint') }}

    @endcan @can('cancel', $prescription) {{-- Two different endings, kept apart on purpose. Reissuing replaces this prescription with a corrected one; cancelling ends it and leaves nothing in its place. --}} @if ($prescription->status->isDispensable())
    @csrf @endif
    @csrf
    @endcan
    {{-- The review, rendered outside the two columns. A modal inside the sidebar inherits that column's stacking and clipping, and on a narrow screen it opens as a panel trapped in a scrolling box rather than over the page. --}} @can('issue', $prescription)
    @csrf
    {{ $patient?->name ?? '—' }} {{ $prescription->reference }}
    {{-- The allergies this prescription trips, repeated here rather than left in the sidebar behind the overlay — the sidebar is the one place somebody cannot look while this is open. --}} @if ($warnings !== [])

    {{ __('prescriptions::messages.allergy.heading') }}

      @foreach ($warnings as $warning)
    • {{ $warning->drugName }} — {{ $warning->allergen }} @if ($warning->reaction)({{ $warning->reaction }})@endif {{ $warning->match->label() }}
    • @endforeach
    @endif @forelse ($prescription->items as $item)
    {{ $item->drug_name }} @if ($item->strength) {{ $item->strength }} @endif @if ($item->is_controlled) {{ __('prescriptions::messages.items.controlled') }} @endif
    {{ $item->directions() }}
    @if ($item->indication)
    {{ __('prescriptions::messages.items.indication') }}: {{ $item->indication }}
    @endif @if ($item->instructions)
    {{ $item->instructions }}
    @endif
    @empty
    {{ __('prescriptions::messages.prescriptions.review_empty') }}
    @endforelse {{-- Only when a conflict was found: issuing over one has to be a decision somebody wrote down. Asked here, where the warning it answers is on the same screen. --}} @if (collect($warnings)->contains(fn ($w) => $w->requiresOverrideReason()))
    @endif
    {{-- Disabled on an empty prescription only to keep somebody from pressing it; the service refuses an empty issue regardless, which is what actually enforces it. --}}
    @endcan @endsection