startOfDay(); $rangeFrom = $from ? Carbon::parse($from)->startOfDay() : now()->startOfMonth(); $rangeTo = $to ? Carbon::parse($to)->endOfDay() : now()->endOfDay(); $departmentIds = $this->shell->departmentIds($organization, 'surgery', $ownerRef, $branchId); $appointmentBase = Appointment::owned($ownerRef) ->where('organization_id', $organization->id) ->when($departmentIds !== [], fn ($q) => $q->whereIn('department_id', $departmentIds)) ->when($departmentIds === [], fn ($q) => $q->whereRaw('1 = 0')) ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)); $arrivalsToday = (clone $appointmentBase) ->where('checked_in_at', '>=', $todayStart) ->count(); $completedToday = (clone $appointmentBase) ->where('status', Appointment::STATUS_COMPLETED) ->where('completed_at', '>=', $todayStart) ->count(); $visitIds = (clone $appointmentBase)->whereNotNull('visit_id')->pluck('visit_id'); $openVisitIds = Visit::owned($ownerRef) ->where('organization_id', $organization->id) ->whereIn('id', $visitIds->isEmpty() ? [0] : $visitIds) ->whereIn('status', [Visit::STATUS_OPEN, Visit::STATUS_IN_PROGRESS]) ->pluck('id'); $preopOpen = Visit::owned($ownerRef) ->where('organization_id', $organization->id) ->whereIn('id', $openVisitIds->isEmpty() ? [0] : $openVisitIds) ->whereIn('specialty_stage', ['history', 'exam', 'investigation', 'plan']) ->count(); $planRecords = SpecialtyClinicalRecord::owned($ownerRef) ->where('organization_id', $organization->id) ->where('module_key', 'surgery') ->where('record_type', 'surg_plan') ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->whereBetween('recorded_at', [$rangeFrom, $rangeTo]) ->get(); $diagnosisBreakdown = $planRecords ->groupBy(fn (SpecialtyClinicalRecord $r) => (string) ($r->payload['diagnosis'] ?? 'Unknown')) ->map(fn (Collection $rows, string $diagnosis) => [ 'diagnosis' => $diagnosis, 'total' => $rows->count(), ]) ->values() ->sortByDesc('total') ->values(); $procedureRecords = SpecialtyClinicalRecord::owned($ownerRef) ->where('organization_id', $organization->id) ->where('module_key', 'surgery') ->where('record_type', 'surg_procedure') ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->whereBetween('recorded_at', [$rangeFrom, $rangeTo]) ->get(); $procedureBreakdown = $procedureRecords ->groupBy(fn (SpecialtyClinicalRecord $r) => (string) ($r->payload['procedure'] ?? 'Unknown')) ->map(fn (Collection $rows, string $procedure) => [ 'procedure' => $procedure, 'total' => $rows->count(), ]) ->values() ->sortByDesc('total') ->values(); $completedVisits = Visit::owned($ownerRef) ->where('organization_id', $organization->id) ->whereIn('id', $visitIds->isEmpty() ? [0] : $visitIds) ->where('status', Visit::STATUS_COMPLETED) ->whereBetween('completed_at', [$rangeFrom, $rangeTo]) ->whereNotNull('checked_in_at') ->whereNotNull('completed_at') ->get(); $avgLos = null; if ($completedVisits->isNotEmpty()) { $avgLos = round($completedVisits->avg(function (Visit $visit) { return $visit->checked_in_at->diffInMinutes($visit->completed_at); }), 1); } $serviceLabels = collect($this->shell->provisionedServices($organization, 'surgery')) ->pluck('label') ->filter() ->values() ->all(); $revenueByService = BillLineItem::query() ->where('owner_ref', $ownerRef) ->where('source_type', 'specialty_service') ->whereIn('description', $serviceLabels ?: ['__none__']) ->whereBetween('created_at', [$rangeFrom, $rangeTo]) ->whereHas('bill', function ($q) use ($organization, $visitIds) { $q->where('organization_id', $organization->id) ->whereIn('visit_id', $visitIds->isEmpty() ? [0] : $visitIds) ->whereNotIn('status', [Bill::STATUS_VOID]); }) ->selectRaw('description, count(*) as total, sum(total_minor) as amount_minor') ->groupBy('description') ->orderByDesc('amount_minor') ->get(); return [ 'arrivals_today' => $arrivalsToday, 'completed_today' => $completedToday, 'preop_open' => $preopOpen, 'diagnosis_breakdown' => $diagnosisBreakdown, 'procedure_breakdown' => $procedureBreakdown, 'avg_los_minutes' => $avgLos, 'revenue_by_service' => $revenueByService, 'from' => $rangeFrom->toDateString(), 'to' => $rangeTo->toDateString(), ]; } }