query( "SELECT id, nombre, sort_order FROM turnero_lugares WHERE activo = 1 AND tipo = 'recepcion' ORDER BY sort_order ASC" ); $escritoriosRec = $stmtDesks->fetchAll(PDO::FETCH_ASSOC); $activosRecepcion = []; foreach ($escritoriosRec as $desk) { // El turno activo de este escritorio: el más reciente asociado a él $stmtT = $pdo->prepare( "SELECT t.id, t.codigo, t.numero, t.estado, t.paciente_nombre, t.paciente_id, t.llamado_recepcion_at 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 = 'en_recepcion' AND (t.recepcion_desk_id = ? OR t.recepcion_desk_id IS NULL) ORDER BY t.llamado_recepcion_at DESC LIMIT 1" ); $stmtT->execute([$sesionId, (int)$desk['id']]); $turno = $stmtT->fetch(PDO::FETCH_ASSOC) ?: null; $activosRecepcion[] = [ 'desk_id' => (int)$desk['id'], 'desk_nombre'=> $desk['nombre'], 'sort_order' => (int)$desk['sort_order'], 'turno' => $turno, ]; } // Si no hay escritorios configurados, mostrar todos en_recepcion sin desk if (empty($escritoriosRec)) { $stmtRec = $pdo->prepare( "SELECT t.id, t.codigo, t.numero, t.estado, t.paciente_nombre, t.paciente_id, t.llamado_recepcion_at 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 = 'en_recepcion' ORDER BY t.llamado_recepcion_at DESC" ); $stmtRec->execute([$sesionId]); foreach ($stmtRec->fetchAll(PDO::FETCH_ASSOC) as $i => $t) { $activosRecepcion[] = [ 'desk_id' => 0, 'desk_nombre'=> 'Recepción ' . ($i + 1), 'sort_order' => $i, 'turno' => $t, ]; } // Si no hay ninguno activo, mostrar un panel vacío if (empty($activosRecepcion)) { $activosRecepcion[] = ['desk_id' => 0, 'desk_nombre' => 'Recepción', 'sort_order' => 0, 'turno' => null]; } } // ── 2. Estaciones de Muestras activas + su turno ───────────── $stmtLugares = $pdo->query( "SELECT id, nombre, sort_order FROM turnero_lugares WHERE activo = 1 AND tipo = 'muestras' ORDER BY sort_order ASC" ); $lugares = $stmtLugares->fetchAll(PDO::FETCH_ASSOC); $lugaresActivos = []; foreach ($lugares as $lugar) { $stmtActivo = $pdo->prepare( "SELECT t.id, t.codigo, t.numero, t.estado, t.paciente_nombre, t.paciente_id, t.llamado_lugar_at 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 = 'en_servicio' AND t.lugar_destino_id = ? ORDER BY t.llamado_lugar_at DESC LIMIT 1" ); $stmtActivo->execute([$sesionId, (int)$lugar['id']]); $turnoActivo = $stmtActivo->fetch(PDO::FETCH_ASSOC) ?: null; $lugaresActivos[] = [ 'lugar_id' => (int)$lugar['id'], 'lugar_nombre'=> $lugar['nombre'], 'sort_order' => (int)$lugar['sort_order'], 'turno' => $turnoActivo, ]; } // ── 3. Cola en espera (pendientes por llamar) ───────────────── $stmtCola = $pdo->prepare( "SELECT t.id, t.codigo, t.numero, t.estado, t.paciente_nombre, t.creado_at, p.codigo AS prioridad_codigo, p.nombre AS prioridad_nombre, p.color AS prioridad_color, p.orden_peso FROM turnero_turnos t JOIN turnero_prioridades p ON p.id = t.prioridad_id WHERE t.sesion_id = ? AND t.estado = 'espera' ORDER BY p.orden_peso ASC, t.creado_at ASC" ); $stmtCola->execute([$sesionId]); $cola = $stmtCola->fetchAll(PDO::FETCH_ASSOC); // ── 4. Estadísticas ─────────────────────────────────────────── $stmtStats = $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 IN ('en_recepcion','en_espera_lugar', 'en_servicio')) AS en_atencion, 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 = ?" ); $stmtStats->execute([$sesionId]); $stats = $stmtStats->fetch(PDO::FETCH_ASSOC); jsonOk([ 'sesion_id' => $sesionId, 'sesion_cerrada' => $sesionCerrada, 'activos_recepcion'=> $activosRecepcion, // array de desks con su turno 'lugares' => $lugaresActivos, // array de estaciones de muestras 'cola' => $cola, 'stats' => $stats, 'timestamp' => date('c'), ]);