startOfDay(); $rangeFrom = $from ? Carbon::parse($from)->startOfDay() : now()->startOfMonth(); $rangeTo = $to ? Carbon::parse($to)->endOfDay() : now()->endOfDay(); $departmentIds = $this->shell->departmentIds($organization, 'womens_health', $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'); $highRiskOpen = SpecialtyClinicalRecord::owned($ownerRef) ->where('organization_id', $organization->id) ->where('module_key', 'womens_health') ->where('record_type', 'mat_plan') ->whereIn('visit_id', $openVisitIds->isEmpty() ? [0] : $openVisitIds) ->get() ->filter(function (SpecialtyClinicalRecord $r) { $risk = strtolower((string) ($r->payload['risk_category'] ?? '')); return str_contains($risk, 'high'); }) ->count(); $planRecords = SpecialtyClinicalRecord::owned($ownerRef) ->where('organization_id', $organization->id) ->where('module_key', 'womens_health') ->where('record_type', 'mat_plan') ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->whereBetween('recorded_at', [$rangeFrom, $rangeTo]) ->get(); $riskBreakdown = $planRecords ->groupBy(fn (SpecialtyClinicalRecord $r) => (string) ($r->payload['risk_category'] ?? 'Unknown')) ->map(fn (Collection $rows, string $risk) => [ 'risk' => $risk, 'total' => $rows->count(), ]) ->values() ->sortByDesc('total') ->values(); $postnatalRecords = SpecialtyClinicalRecord::owned($ownerRef) ->where('organization_id', $organization->id) ->where('module_key', 'womens_health') ->where('record_type', 'postnatal_note') ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->whereBetween('recorded_at', [$rangeFrom, $rangeTo]) ->get(); $postnatalOutcomes = $postnatalRecords ->groupBy(fn (SpecialtyClinicalRecord $r) => (string) ($r->payload['outcome'] ?? 'Unknown')) ->map(fn (Collection $rows, string $outcome) => [ 'outcome' => $outcome, '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, 'womens_health')) ->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, 'high_risk_open' => $highRiskOpen, 'risk_breakdown' => $riskBreakdown, 'postnatal_outcomes' => $postnatalOutcomes, 'avg_los_minutes' => $avgLos, 'revenue_by_service' => $revenueByService, 'from' => $rangeFrom->toDateString(), 'to' => $rangeTo->toDateString(), ]; } }