@extends('layouts.app') @section('title', 'Pharmacy Health') @php $grade = \App\Models\StockCount::grade($summary['score']); [$gradeLabel, $gradeTone] = $grade ? \App\Models\StockCount::GRADES[$grade] : ['No counts yet', 'secondary']; $statusInfo = \App\Services\PharmacyHealth::STAFF_STATUS; $trend = $counts->where('status', 'finished')->sortBy('finished_at')->take(-20)->values(); @endphp @section('content')

Pharmacy Health

Shelf counts against the system: is stock where the system says it is? Missing stock is the pharmacy's overall result.

@if($open)
A count is in progress: {{ $open->scope_label }}, started {{ $open->created_at->diffForHumans() }} by {{ $open->user->name ?? 'someone' }}. Continue counting
@endif
@foreach([7 => '7 days', 30 => '30 days', 90 => '90 days', 365 => '1 year'] as $d => $label) {{ $label }} @endforeach
to
{{ $summary['score'] !== null ? rtrim(rtrim(number_format($summary['score'], 1), '0'), '.') . '%' : '–' }}
Health score, {{ $from->format('d M') }} – {{ $to->format('d M Y') }}
{{ $gradeLabel }}
95%+ healthy · 85–95% watch · below 85% at risk
@if($summary['last'])
Last count {{ $summary['last']->finished_at->diffForHumans() }}
@endif
@foreach([ ['Counts', number_format($summary['counts']), number_format($summary['lines']) . ' products checked', 'bi-clipboard-check', 'secondary'], ['Short on the shelf', number_format($summary['short_lines']), formatCurrency($summary['shortage_value']) . ' at cost', 'bi-exclamation-triangle-fill', $summary['short_lines'] ? 'danger' : 'success'], ['More than system', number_format($summary['over_lines']), 'Sales or deliveries not recorded?', 'bi-plus-circle', $summary['over_lines'] ? 'warning' : 'secondary'], ['Staff to review', number_format($staff->where('status', 'review')->count()), $staff->where('status', 'watch')->count() . ' to watch', 'bi-person-exclamation', $staff->where('status', 'review')->count() ? 'danger' : 'success'], ] as [$label, $value, $hint, $icon, $tone])
{{ $label }}
{{ $value }}
{{ $hint }}
@endforeach @if($trend->count() > 1)
Health of each count (oldest to newest)
@foreach($trend as $c) @php $t = \App\Models\StockCount::GRADES[\App\Models\StockCount::grade((float) $c->health_score)][1]; @endphp @endforeach
@endif
Staff warnings

From Loss Prevention in the same period: deleted or edited sales, voids, cash shortages and similar. Stock counts are not put against anyone.

@forelse($staff as $s) @php [$sLabel, $sTone, $sHint] = $statusInfo[$s->status]; @endphp @empty @endforelse
PersonShiftsSalesWarningsStatus
{{ $s->user->name }} {{ $s->shifts }} {{ formatCurrency($s->sales_total) }}
{{ $s->sales_count }} sales
{{ $s->warnings }} @if($s->serious)
{{ $s->serious }} serious
@endif
{{ $sLabel }}
No staff activity in this period.
Stock counts
@forelse($counts as $c) @php $cg = $c->isOpen() ? null : \App\Models\StockCount::grade((float) $c->health_score); @endphp @if($c->isOpen()) @else @endif @empty @endforelse
DateProductsCounted byMatchedShort Missing (cost)Health
{{ ($c->finished_at ?? $c->created_at)->format('d M Y H:i') }} {{ $c->scope_label }}@if($c->note)
{{ $c->note }}
@endif
{{ $c->user->name ?? '-' }}In progress{{ $c->lines_matched }} / {{ $c->lines_counted }} {{ $c->lines_short }} {{ formatCurrency((float) $c->shortage_value) }} {{ rtrim(rtrim(number_format((float) $c->health_score, 1), '0'), '.') }}%{{ $c->isOpen() ? 'Continue' : 'View' }}
No counts in this period{{ $search ? ' matching "' . $search . '"' : '' }}. Start one when you next visit.
@if($errors->any()) @endif @endsection