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;
}
}