From 70fda3dacc4dc9380a5f301045916ef314036278 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 28 Jul 2026 08:40:49 -0500 Subject: [PATCH] =?UTF-8?q?fix(turnero):=20dos=20correcciones=20de=20estad?= =?UTF-8?q?o=20y=20redirecci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. App::bacteDefaultUrl() ahora busca también por token cookie (antes solo buscaba por IP), consistente con login.php y lugar.php. 2. cambiarEstadoTurno(): cuando el servidor devuelve 422 (transición inválida porque otro operador cambió el estado), muestra mensaje claro y refresca la UI en lugar de mostrar el error técnico bruto "Transición 'en_recepcion' → 'finalizado' no está permitida". Co-Authored-By: Claude Sonnet 4.6 --- core/App.php | 33 +++++++++++++++++++-------------- modules/turnero/views/lugar.php | 12 +++++++++++- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/core/App.php b/core/App.php index edb12e2..112c9c1 100644 --- a/core/App.php +++ b/core/App.php @@ -162,25 +162,30 @@ class App $base = '/erp.php?m=turnero&v=lugar&lugar_id='; try { $pdo = Database::getInstance()->getConnection(); - $ip = self::clientIp(); - // ¿IP registrada? - $dev = $pdo->prepare( - "SELECT lugar_id FROM turnero_dispositivos WHERE ip = ? AND activo = 1 LIMIT 1" - ); - $dev->execute([$ip]); - $row = $dev->fetch(PDO::FETCH_ASSOC); - if ($row) { - return $base . (int)$row['lugar_id']; + // 1. Por token de navegador + $tok = trim($_COOKIE['turnero_token'] ?? ''); + if ($tok) { + $s = $pdo->prepare( + "SELECT lugar_id FROM turnero_dispositivos WHERE token = ? AND activo = 1 LIMIT 1" + ); + $s->execute([$tok]); + $row = $s->fetch(PDO::FETCH_ASSOC); + if ($row) return $base . (int)$row['lugar_id']; } - // Primer lugar de toma de muestras + // 2. Por IP + $ip = self::clientIp(); + $s = $pdo->prepare( + "SELECT lugar_id FROM turnero_dispositivos WHERE ip = ? AND token IS NULL AND activo = 1 LIMIT 1" + ); + $s->execute([$ip]); + $row = $s->fetch(PDO::FETCH_ASSOC); + if ($row) return $base . (int)$row['lugar_id']; + // 3. Primer lugar de toma de muestras $first = $pdo->query( "SELECT id FROM turnero_lugares WHERE activo=1 AND tipo='muestras' ORDER BY sort_order LIMIT 1" )->fetch(PDO::FETCH_ASSOC); - if ($first) { - return $base . (int)$first['id']; - } + if ($first) return $base . (int)$first['id']; } catch (\Throwable $_) {} - // Fallback: turnero sin vista específica return '/erp.php?m=turnero'; } diff --git a/modules/turnero/views/lugar.php b/modules/turnero/views/lugar.php index fe0f631..a97a6a0 100644 --- a/modules/turnero/views/lugar.php +++ b/modules/turnero/views/lugar.php @@ -2014,7 +2014,17 @@ async function cambiarEstadoTurno(nuevoEstado) { body: JSON.stringify({ turno_id: turnoActivo.id, nuevo_estado: nuevoEstado }), }); const json = await res.json(); - if (!json.ok) { mostrarError(json.error); return; } + if (!json.ok) { + // Si el estado cambió por otro operador, refrescar UI en lugar de mostrar error técnico + if (res.status === 422) { + mostrarError('El estado del turno cambió desde otro puesto. Actualizando…'); + await cargarCola(); + await recuperarTurnoActivo(); + } else { + mostrarError(json.error); + } + return; + } resetFicha(); cargarCola(); } catch (err) {