true, 'activo' => null, 'cola' => [], 'stats' => [ 'total' => 0, 'en_espera' => 0, 'en_recepcion' => 0, 'en_espera_lugar' => 0, 'en_servicio' => 0, 'finalizados' => 0, 'no_atendidos' => 0, 'tiempo_promedio_atencion' => null, ], 'timestamp' => date('c'), ]); exit; } // ── Cola según área ─────────────────────────────────────────── if ($area === 'recepcion') { // Recepción: todos los turnos en espera/en_recepcion $inEstados = "'espera', 'en_recepcion'"; $stmt = $pdo->prepare( "SELECT t.id, t.codigo, t.numero, t.estado, t.paciente_nombre, t.recepcion_desk_id, t.creado_at, t.llamado_recepcion_at, t.llamado_lugar_at, p.codigo AS prioridad_codigo, p.nombre AS prioridad_nombre, p.color AS prioridad_color, p.orden_peso, COALESCE(s.solo_muestras, 0) AS solo_muestras FROM turnero_turnos t JOIN turnero_prioridades p ON p.id = t.prioridad_id LEFT JOIN turnero_solicitudes s ON s.turno_id = t.id WHERE t.sesion_id = ? AND t.estado IN ($inEstados) ORDER BY p.orden_peso ASC, t.creado_at ASC" ); $stmt->execute([$sesionId]); } else { // Lugar: cola = en_espera_lugar del grupo + en_servicio en ESTA estación $grupoIds = lugarIdsDeGrupo($lugarId); $inLugares = implode(',', array_map('intval', $grupoIds)); $cols = "t.id, t.codigo, t.numero, t.estado, t.paciente_nombre, t.recepcion_desk_id, t.creado_at, t.llamado_recepcion_at, t.llamado_lugar_at, p.codigo AS prioridad_codigo, p.nombre AS prioridad_nombre, p.color AS prioridad_color, p.orden_peso, COALESCE(s.solo_muestras, 0) AS solo_muestras"; $stmt = $pdo->prepare( "SELECT * FROM ( (SELECT $cols FROM turnero_turnos t JOIN turnero_prioridades p ON p.id = t.prioridad_id LEFT JOIN turnero_solicitudes s ON s.turno_id = t.id WHERE t.sesion_id = ? AND t.estado = 'en_espera_lugar' AND t.lugar_destino_id IN ($inLugares)) UNION ALL (SELECT $cols FROM turnero_turnos t JOIN turnero_prioridades p ON p.id = t.prioridad_id LEFT JOIN turnero_solicitudes s ON s.turno_id = t.id WHERE t.sesion_id = ? AND t.estado = 'en_servicio' AND t.lugar_destino_id = ?) ) AS cola_union ORDER BY solo_muestras DESC, orden_peso ASC, creado_at ASC" ); $stmt->execute([$sesionId, $sesionId, $lugarId]); } $cola = $stmt->fetchAll(PDO::FETCH_ASSOC); // Enriquecer con datos de toma progresiva (cuenta regresiva en tarjetas de cola) if (!empty($cola)) { $turnoIds = implode(',', array_map('intval', array_column($cola, 'id'))); $tomaRows = $pdo->query( "SELECT tc.turno_id, tc.siguiente_toma_at FROM turnero_consentimientos tc JOIN lab_formularios f ON f.id = tc.formulario_id AND f.es_toma_progresiva = 1 WHERE tc.turno_id IN ($turnoIds) AND tc.estado = 'en_progreso' ORDER BY tc.siguiente_toma_at ASC" )->fetchAll(PDO::FETCH_ASSOC); $tomaInfo = []; foreach ($tomaRows as $row) { if (!isset($tomaInfo[$row['turno_id']])) { $tomaInfo[$row['turno_id']] = $row['siguiente_toma_at']; } } foreach ($cola as &$t) { $t['en_toma_progresiva'] = isset($tomaInfo[$t['id']]) ? 1 : 0; $t['siguiente_toma_at'] = $tomaInfo[$t['id']] ?? null; } unset($t); } // ── Turno actualmente en pantalla (último llamado) ──────────── $campoLlamado = $area === 'recepcion' ? 'llamado_recepcion_at' : 'llamado_lugar_at'; $estadoActivo = $area === 'recepcion' ? "'en_recepcion'" : "'en_servicio'"; // Activo: para lugar filtrar SOLO por esta estación (ya fue asignada al llamar) $filtroActivo = $area === 'lugar' ? 'AND t.lugar_destino_id = ?' : ''; $bindActivo = $area === 'lugar' ? [$sesionId, $lugarId] : [$sesionId]; $stmt = $pdo->prepare( "SELECT t.id, t.codigo, t.numero, t.estado, t.paciente_nombre, t.{$campoLlamado} AS llamado_at, p.codigo AS prioridad_codigo, p.nombre AS prioridad_nombre, p.color AS prioridad_color FROM turnero_turnos t JOIN turnero_prioridades p ON p.id = t.prioridad_id WHERE t.sesion_id = ? AND t.estado = {$estadoActivo} {$filtroActivo} ORDER BY t.{$campoLlamado} DESC LIMIT 1" ); $stmt->execute($bindActivo); $activo = $stmt->fetch(PDO::FETCH_ASSOC) ?: null; // ── Estadísticas de la sesión ───────────────────────────────── $stmt = $pdo->prepare( "SELECT COUNT(*) AS total, SUM(estado = 'espera') AS en_espera, SUM(estado = 'en_recepcion') AS en_recepcion, SUM(estado = 'en_espera_lugar') AS en_espera_lugar, SUM(estado = 'en_servicio') AS en_servicio, SUM(estado = 'finalizado') AS finalizados, SUM(estado IN ('ausente','cancelado')) AS no_atendidos, SEC_TO_TIME( AVG( CASE WHEN fin_lugar_at IS NOT NULL AND creado_at IS NOT NULL THEN TIMESTAMPDIFF(SECOND, creado_at, fin_lugar_at) ELSE NULL END ) ) AS tiempo_promedio_atencion FROM turnero_turnos WHERE sesion_id = ?" ); $stmt->execute([$sesionId]); $stats = $stmt->fetch(PDO::FETCH_ASSOC); jsonOk([ 'sesion_id' => $sesionId, 'area' => $area, 'lugar_id' => $lugarId, 'activo' => $activo, 'cola' => $cola, 'stats' => $stats, 'timestamp' => date('c'), ]);