prepare( 'SELECT id, inicio_at, fin_at FROM turnero_sesiones WHERE fecha = ? LIMIT 1' ); $stmtSesion->execute([$fecha]); $sesion = $stmtSesion->fetch(PDO::FETCH_ASSOC); if (!$sesion) { jsonOk([ 'fecha' => $fecha, 'sesion' => null, 'resumen' => ['total' => 0, 'atendidos' => 0, 'en_espera' => 0, 'ausentes' => 0, 'cancelados' => 0, 'tiempo_promedio_min' => null], 'por_prioridad' => [], 'por_lugar' => [], 'turnos' => [], ]); } $sesionId = (int)$sesion['id']; // ── 2. Resumen global ───────────────────────────────────────── $stmtRes = $pdo->prepare( "SELECT COUNT(*) AS total, SUM(estado IN ('finalizado','en_servicio')) AS atendidos, SUM(estado IN ('espera','en_recepcion','en_espera_lugar')) AS en_espera, SUM(estado = 'ausente') AS ausentes, SUM(estado = 'cancelado') AS cancelados, ROUND( AVG( CASE WHEN inicio_recepcion_at IS NOT NULL AND creado_at IS NOT NULL THEN TIMESTAMPDIFF(SECOND, creado_at, inicio_recepcion_at) / 60.0 END ), 1 ) AS tiempo_espera_promedio_min, ROUND( AVG( CASE WHEN fin_lugar_at IS NOT NULL AND inicio_lugar_at IS NOT NULL THEN TIMESTAMPDIFF(SECOND, inicio_lugar_at, fin_lugar_at) / 60.0 END ), 1 ) AS tiempo_servicio_promedio_min FROM turnero_turnos WHERE sesion_id = ?" ); $stmtRes->execute([$sesionId]); $resumen = $stmtRes->fetch(PDO::FETCH_ASSOC); // ── 3. Desglose por prioridad ───────────────────────────────── $stmtPri = $pdo->prepare( "SELECT p.codigo, p.nombre, p.color, COUNT(t.id) AS total, SUM(t.estado IN ('finalizado','en_servicio')) AS atendidos, SUM(t.estado IN ('espera','en_recepcion','en_espera_lugar')) AS pendientes, SUM(t.estado = 'ausente') AS ausentes FROM turnero_turnos t JOIN turnero_prioridades p ON p.id = t.prioridad_id WHERE t.sesion_id = ? GROUP BY p.id ORDER BY p.orden_peso ASC" ); $stmtPri->execute([$sesionId]); $porPrioridad = $stmtPri->fetchAll(PDO::FETCH_ASSOC); // ── 4. Desglose por lugar ───────────────────────────────────── $stmtLug = $pdo->prepare( "SELECT l.nombre AS lugar, COUNT(t.id) AS total, SUM(t.estado IN ('finalizado','en_servicio')) AS atendidos, SUM(t.estado IN ('en_espera_lugar')) AS en_espera, ROUND(AVG( CASE WHEN t.fin_lugar_at IS NOT NULL AND t.inicio_lugar_at IS NOT NULL THEN TIMESTAMPDIFF(SECOND, t.inicio_lugar_at, t.fin_lugar_at) / 60.0 END ), 1) AS tiempo_servicio_promedio_min FROM turnero_turnos t JOIN turnero_lugares l ON l.id = t.lugar_destino_id WHERE t.sesion_id = ? GROUP BY l.id ORDER BY l.sort_order ASC, l.nombre ASC" ); $stmtLug->execute([$sesionId]); $porLugar = $stmtLug->fetchAll(PDO::FETCH_ASSOC); // ── 5. Lista de turnos del día ──────────────────────────────── $stmtTurnos = $pdo->prepare( "SELECT t.id, t.codigo, t.numero, t.estado, t.paciente_nombre, t.paciente_cel, t.creado_at, t.inicio_recepcion_at, t.fin_recepcion_at, t.inicio_lugar_at, t.fin_lugar_at, p.codigo AS prioridad_codigo, p.nombre AS prioridad_nombre, p.color AS prioridad_color, l.nombre AS lugar_nombre, s.nombre_completo AS paciente_bd, ROUND(TIMESTAMPDIFF(SECOND, t.creado_at, COALESCE(t.inicio_recepcion_at, NOW())) / 60.0, 1) AS espera_min, ROUND(TIMESTAMPDIFF(SECOND, t.inicio_lugar_at, COALESCE(t.fin_lugar_at, NOW())) / 60.0, 1) AS servicio_min FROM turnero_turnos t JOIN turnero_prioridades p ON p.id = t.prioridad_id LEFT JOIN turnero_lugares l ON l.id = t.lugar_destino_id LEFT JOIN turnero_solicitudes ts ON ts.turno_id = t.id LEFT JOIN lab_pacientes s ON s.id = ts.paciente_id WHERE t.sesion_id = ? ORDER BY t.numero ASC" ); $stmtTurnos->execute([$sesionId]); $turnos = $stmtTurnos->fetchAll(PDO::FETCH_ASSOC); // ── 6. Consentimientos del día ──────────────────────────────── $stmtcons = $pdo->prepare( "SELECT tc.estado, COUNT(*) AS cnt FROM turnero_consentimientos tc JOIN turnero_turnos t ON t.id = tc.turno_id WHERE t.sesion_id = ? GROUP BY tc.estado" ); $stmtcons->execute([$sesionId]); $consentStats = []; foreach ($stmtcons->fetchAll(PDO::FETCH_ASSOC) as $r) { $consentStats[$r['estado']] = (int)$r['cnt']; } jsonOk([ 'fecha' => $fecha, 'sesion' => [ 'id' => $sesionId, 'inicio' => $sesion['inicio_at'] ? date('H:i', strtotime($sesion['inicio_at'])) : null, 'fin' => $sesion['fin_at'] ? date('H:i', strtotime($sesion['fin_at'])) : null, 'abierta' => $sesion['fin_at'] === null, ], 'resumen' => $resumen, 'por_prioridad' => $porPrioridad, 'por_lugar' => $porLugar, 'consent_stats' => $consentStats, 'turnos' => $turnos, ]);