*/ public function overview(string $ownerRef, int $organizationId, ?int $branchId = null): array { $stats = $this->dashboard->forOrganization($ownerRef, $organizationId, $branchId); $today = Ticket::owned($ownerRef) ->where('organization_id', $organizationId) ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->whereDate('issued_at', today()); $bySource = (clone $today) ->selectRaw('source, COUNT(*) as total') ->groupBy('source') ->pluck('total', 'source') ->all(); $byPriority = (clone $today) ->selectRaw('priority, COUNT(*) as total') ->groupBy('priority') ->pluck('total', 'priority') ->all(); $appointmentsToday = QueueAppointment::owned($ownerRef) ->where('organization_id', $organizationId) ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->whereDate('scheduled_at', today()) ->count(); $feedbackAvg = CustomerFeedback::owned($ownerRef) ->where('organization_id', $organizationId) ->when($branchId, fn ($q) => $q->whereHas('ticket', fn ($t) => $t->where('branch_id', $branchId))) ->where('created_at', '>=', now()->subDays(30)) ->avg('rating'); $queueLoad = ServiceQueue::owned($ownerRef) ->where('organization_id', $organizationId) ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->where('is_active', true) ->withCount(['tickets as waiting_count' => fn ($q) => $q->where('status', 'waiting')]) ->orderByDesc('waiting_count') ->limit(5) ->get() ->map(fn ($q) => ['name' => $q->name, 'waiting' => $q->waiting_count]) ->all(); return array_merge($stats, [ 'tickets_by_source' => $bySource, 'tickets_by_priority' => $byPriority, 'appointments_today' => $appointmentsToday, 'feedback_avg_30d' => round((float) $feedbackAvg, 1), 'busiest_queues' => $queueLoad, ]); } /** * @return list */ public function dailyTrend(string $ownerRef, int $organizationId, int $days = 14, ?int $branchId = null): array { $from = now()->subDays($days - 1)->startOfDay(); $issued = Ticket::owned($ownerRef) ->where('organization_id', $organizationId) ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->where('issued_at', '>=', $from) ->selectRaw('DATE(issued_at) as d, COUNT(*) as c') ->groupBy('d') ->pluck('c', 'd'); $completed = Ticket::owned($ownerRef) ->where('organization_id', $organizationId) ->when($branchId, fn ($q) => $q->where('branch_id', $branchId)) ->where('status', 'completed') ->where('completed_at', '>=', $from) ->selectRaw('DATE(completed_at) as d, COUNT(*) as c') ->groupBy('d') ->pluck('c', 'd'); $trend = []; for ($i = 0; $i < $days; $i++) { $date = $from->copy()->addDays($i)->toDateString(); $trend[] = [ 'date' => $date, 'issued' => (int) ($issued[$date] ?? 0), 'completed' => (int) ($completed[$date] ?? 0), ]; } return $trend; } }