From b11a7f5f9867d5089a6bbe50b2a6b4f3b214f41e Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 16 Jun 2026 13:20:13 -0500 Subject: [PATCH] up --- modules/turnero/api/get_cola.php | 73 +++++++++++++--------------- modules/turnero/api/llamar_turno.php | 32 +++++++++--- modules/turnero/views/lugar.php | 43 ++++++++++++++-- 3 files changed, 99 insertions(+), 49 deletions(-) diff --git a/modules/turnero/api/get_cola.php b/modules/turnero/api/get_cola.php index e913e29..e77f01b 100644 --- a/modules/turnero/api/get_cola.php +++ b/modules/turnero/api/get_cola.php @@ -49,54 +49,49 @@ if ($sesionCerrada) { // ── Cola según área ─────────────────────────────────────────── if ($area === 'recepcion') { - $estadosCola = ["'espera'", "'en_recepcion'"]; + // Recepción: todos los turnos en espera/en_recepcion + $inEstados = "'espera', 'en_recepcion'"; $filtroLugar = ''; $bindsCola = [$sesionId]; + + $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 + FROM turnero_turnos t + JOIN turnero_prioridades p ON p.id = t.prioridad_id + WHERE t.sesion_id = ? AND t.estado IN ($inEstados) + ORDER BY p.orden_peso ASC, t.creado_at ASC" + ); + $stmt->execute($bindsCola); } else { - $estadosCola = ["'en_espera_lugar'", "'en_servicio'"]; - // Expandir grupo de lugares - $grupoIds = lugarIdsDeGrupo($lugarId); - $inLugares = implode(',', array_map('intval', $grupoIds)); - $filtroLugar = "AND t.lugar_destino_id IN ($inLugares)"; - $bindsCola = [$sesionId]; + // Lugar: cola compartida (grupo) solo en_espera_lugar + $grupoIds = lugarIdsDeGrupo($lugarId); + $inLugares = implode(',', array_map('intval', $grupoIds)); + + $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 + FROM turnero_turnos t + JOIN turnero_prioridades p ON p.id = t.prioridad_id + WHERE t.sesion_id = ? + AND t.estado = 'en_espera_lugar' + AND t.lugar_destino_id IN ($inLugares) + ORDER BY p.orden_peso ASC, t.creado_at ASC" + ); + $stmt->execute([$sesionId]); } - -$inEstados = implode(', ', $estadosCola); - -$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 - FROM turnero_turnos t - JOIN turnero_prioridades p ON p.id = t.prioridad_id - WHERE t.sesion_id = ? - AND t.estado IN ({$inEstados}) - {$filtroLugar} - ORDER BY p.orden_peso ASC, t.creado_at ASC" -); -$stmt->execute($bindsCola); $cola = $stmt->fetchAll(PDO::FETCH_ASSOC); // ── Turno actualmente en pantalla (último llamado) ──────────── $campoLlamado = $area === 'recepcion' ? 'llamado_recepcion_at' : 'llamado_lugar_at'; $estadoActivo = $area === 'recepcion' ? "'en_recepcion'" : "'en_servicio'"; -if ($area === 'lugar') { - $filtroActivo = "AND t.lugar_destino_id IN ($inLugares)"; - $bindActivo = [$sesionId]; -} else { - $filtroActivo = ''; - $bindActivo = [$sesionId]; -} +// 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, diff --git a/modules/turnero/api/llamar_turno.php b/modules/turnero/api/llamar_turno.php index 5ea6bf9..81f86fb 100644 --- a/modules/turnero/api/llamar_turno.php +++ b/modules/turnero/api/llamar_turno.php @@ -61,12 +61,12 @@ try { } else { // Cola de un Lugar específico: turnos 'en_espera_lugar' asignados a ese lugar if ($turnoId) { - // Llamar uno específico por id + // Llamar uno específico por id (puede ser en_espera_lugar o ya en_servicio para re-llamar) $stmt = $pdo->prepare( 'SELECT t.*, 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.id = ? AND t.estado = "en_espera_lugar"' + WHERE t.id = ? AND t.estado IN ("en_espera_lugar", "en_servicio")' ); $stmt->execute([$turnoId]); $turno = $stmt->fetch(PDO::FETCH_ASSOC); @@ -82,15 +82,33 @@ try { } } + // Re-llamar: si ya está en_servicio en ESTA estación, solo actualiza llamado_at + if ($turno['estado'] === 'en_servicio' && $turno['lugar_destino_id'] == $lugarId) { + $pdo->prepare( + 'UPDATE turnero_turnos SET llamado_lugar_at = NOW() WHERE id = ?' + )->execute([$turno['id']]); + $pdo->commit(); + // Refrescar y retornar + $stmt = $pdo->prepare( + 'SELECT t.*, 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.id = ?' + ); + $stmt->execute([$turno['id']]); + $turnoActualizado = $stmt->fetch(PDO::FETCH_ASSOC); + notificarSSE((int)$turnoActualizado['sesion_id']); + jsonOk(['turno' => $turnoActualizado], "Turno {$turnoActualizado['codigo']} re-llamado"); + } + $stmt = $pdo->prepare( 'UPDATE turnero_turnos - SET estado = "en_servicio", - llamado_lugar_at = NOW(), - inicio_lugar_at = NOW(), - atendido_lugar_por = ? + SET estado = "en_servicio", + llamado_lugar_at = NOW(), + inicio_lugar_at = NOW(), + atendido_lugar_por= ?, + lugar_destino_id = ? WHERE id = ? AND estado = "en_espera_lugar"' ); - $stmt->execute([adminId(), $turno['id']]); + $stmt->execute([adminId(), $lugarId, $turno['id']]); if ($stmt->rowCount() === 0) { $pdo->rollBack(); diff --git a/modules/turnero/views/lugar.php b/modules/turnero/views/lugar.php index 689bfbb..bb759f7 100644 --- a/modules/turnero/views/lugar.php +++ b/modules/turnero/views/lugar.php @@ -320,6 +320,9 @@ require_once __DIR__ . '/../../../shared/components/sidebar.php'; + @@ -364,10 +367,22 @@ document.addEventListener('DOMContentLoaded', () => { }); function iniciarPuesto() { + recuperarTurnoActivo(); // ver si ya hay un turno en_servicio en esta estación cargarCola(); pollingColaId = setInterval(cargarCola, 7000); } +// Recupera el turno en_servicio de ESTA estación (si existe) al cargar la página +async function recuperarTurnoActivo() { + try { + const res = await fetch(`${API}get_cola.php?area=lugar&lugar_id=${lugarId}`); + const json = await res.json(); + if (json.ok && json.activo) { + await abrirFicha(json.activo); + } + } catch (_) {} +} + // ── Selector de lugar ───────────────────────────────────────── function confirmarLugar() { const sel = document.getElementById('sel-lugar-init'); @@ -771,17 +786,39 @@ function actualizarEstadoBadge(estado) { el.textContent = lbl; // Sincronizar botones según estado - const btnIni = document.getElementById('btn-iniciar'); - const btnFin = document.getElementById('btn-finalizar'); - const btnReg = document.getElementById('btn-regresar'); + const btnIni = document.getElementById('btn-iniciar'); + const btnFin = document.getElementById('btn-finalizar'); + const btnReg = document.getElementById('btn-regresar'); + const btnRellamar = document.getElementById('btn-rellamar'); if (estado === 'en_espera_lugar') { btnIni.classList.remove('d-none'); btnIni.disabled = hayPendientes; btnFin.classList.add('d-none'); btnReg.classList.add('d-none'); + btnRellamar.classList.add('d-none'); } else if (estado === 'en_servicio') { btnIni.classList.add('d-none'); btnFin.classList.remove('d-none'); btnReg.classList.remove('d-none'); + btnRellamar.classList.remove('d-none'); + } +} + +async function rellamarTurno() { + if (!turnoActivo) return; + const btn = document.getElementById('btn-rellamar'); + btn.disabled = true; + try { + const res = await fetch(API + 'llamar_turno.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ area: 'lugar', lugar_id: lugarId, turno_id: turnoActivo.id }), + }); + const json = await res.json(); + if (!json.ok) alert('Error: ' + json.error); + } catch (err) { + alert('Error: ' + err.message); + } finally { + btn.disabled = false; } }