plantelUsuarios->pluck('id'); $planteles = Auth::user()->plantelUsuarios; $query = WhatsappLog::query(); if ($request->filled('plantel_id')) { $plantelId = (int) $request->plantel_id; $query->whereNotNull('alumno_id') ->whereHas('alumno.alumnos.plantelUsuarios', function ($q) use ($plantelId) { $q->where('plantels.id', $plantelId); }); } if ($request->filled('promocion_id')) { $query->whereJsonContains('payload->promocion_id', (int) $request->promocion_id); } if ($request->filled('fecha_desde')) { $query->where('created_at', '>=', $request->fecha_desde . ' 00:00:00'); } if ($request->filled('fecha_hasta')) { $query->where('created_at', '<=', $request->fecha_hasta . ' 23:59:59'); } // Métricas siempre sobre todos los tipos (sin filtro de tipo) $enviados = (clone $query)->where('tipo', 'enviado')->count(); $fallidos = (clone $query)->where('tipo', 'error')->count(); $optOuts = (clone $query)->where('tipo', 'opt_out')->count(); $recibidos = (clone $query)->where('tipo', 'recibido')->count(); $entregados = (clone $query)->where('tipo', 'status_delivered')->count(); $leidos = (clone $query)->where('tipo', 'status_read')->count(); // El filtro de tipo solo aplica al listado de logs $logsQuery = clone $query; if ($request->filled('tipo')) { $logsQuery->where('tipo', $request->tipo); } $logsRecientes = $logsQuery ->with('alumno.alumnos') ->latest('created_at') ->paginate(20); $promociones = Promocion::whereHas('planteles', function ($q) use ($plantelesIds) { $q->whereIn('plantels.id', $plantelesIds); })->latest()->get(); return view('promocion.analytics', compact( 'enviados', 'fallidos', 'optOuts', 'recibidos', 'entregados', 'leidos', 'logsRecientes', 'planteles', 'promociones' )); } public function stats(Request $request) { $query = WhatsappLog::query(); if ($request->filled('plantel_id')) { $plantelId = (int) $request->plantel_id; $query->whereNotNull('alumno_id') ->whereHas('alumno.alumnos.plantelUsuarios', function ($q) use ($plantelId) { $q->where('plantels.id', $plantelId); }); } return response()->json([ 'enviados' => (clone $query)->where('tipo', 'enviado')->count(), 'recibidos' => (clone $query)->where('tipo', 'recibido')->count(), 'fallidos' => (clone $query)->where('tipo', 'error')->count(), 'opt_outs' => (clone $query)->where('tipo', 'opt_out')->count(), ]); } public function logs(Request $request) { $query = WhatsappLog::with('alumno.alumnos') ->orderByDesc('created_at'); if ($request->filled('fecha_desde')) { $query->where('created_at', '>=', $request->fecha_desde); } if ($request->filled('fecha_hasta')) { $query->where('created_at', '<=', $request->fecha_hasta . ' 23:59:59'); } if ($request->filled('plantel_id')) { $plantelId = (int) $request->plantel_id; $query->whereNotNull('alumno_id') ->whereHas('alumno.alumnos.plantelUsuarios', function ($q) use ($plantelId) { $q->where('plantels.id', $plantelId); }); } if ($request->filled('tipo')) { $query->where('tipo', $request->tipo); } $logs = $query->paginate(50); return response()->json($logs); } }