From 63da89c31afa033a1f5a63918a526a0ed5e45a12 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 21 Apr 2026 18:13:53 -0500 Subject: [PATCH] up --- migrations/006_turnero_tipos_lugar.sql | 35 ++++ modules/turnero/api/get_display_global.php | 101 +++++++--- modules/turnero/api/save_lugar.php | 10 +- modules/turnero/views/configuracion.php | 212 ++++++++++++++------- modules/turnero/views/display_global.php | 86 +++++---- 5 files changed, 309 insertions(+), 135 deletions(-) create mode 100644 migrations/006_turnero_tipos_lugar.sql diff --git a/migrations/006_turnero_tipos_lugar.sql b/migrations/006_turnero_tipos_lugar.sql new file mode 100644 index 0000000..4925f6e --- /dev/null +++ b/migrations/006_turnero_tipos_lugar.sql @@ -0,0 +1,35 @@ +-- ════════════════════════════════════════════════════════════════ +-- Migration 006 — Tipos de lugar en el Turnero +-- Permite distinguir escritorios de Recepción de estaciones de Muestras. +-- ════════════════════════════════════════════════════════════════ + +-- Añadir columna tipo a turnero_lugares +ALTER TABLE turnero_lugares + ADD COLUMN IF NOT EXISTS tipo + ENUM('recepcion', 'muestras') NOT NULL DEFAULT 'muestras' + COMMENT 'recepcion=ventanilla de recepcion | muestras=estacion de toma de muestras' + AFTER nombre; + +-- Los lugares existentes (Toma de Muestras, Rayos X, etc.) quedan como 'muestras' +-- Los escritorios de recepción se crean desde el panel de configuración. + +-- Insertar escritorios de recepción de ejemplo si no existen +INSERT IGNORE INTO turnero_lugares (id, nombre, tipo, descripcion, activo, sort_order) VALUES +(10, 'Recepción 1', 'recepcion', 'Primer escritorio de recepción', 1, 1), +(11, 'Recepción 2', 'recepcion', 'Segundo escritorio de recepción', 1, 2); + +-- Índice para filtrar por tipo +ALTER TABLE turnero_lugares + ADD INDEX IF NOT EXISTS idx_tipo (tipo); + +-- ──────────────────────────────────────────────────────────────── +-- Añadir recepcion_desk_id a turnero_turnos +-- Permite saber en qué escritorio de recepción fue atendido el turno +-- (opcional: si NULL = recepcionista no seleccionó escritorio) +ALTER TABLE turnero_turnos + ADD COLUMN IF NOT EXISTS recepcion_desk_id INT UNSIGNED DEFAULT NULL + COMMENT 'FK turnero_lugares.id (tipo=recepcion) — escritorio que llamó el turno' + AFTER lugar_destino_id; + +ALTER TABLE turnero_turnos + ADD INDEX IF NOT EXISTS idx_rec_desk (recepcion_desk_id); diff --git a/modules/turnero/api/get_display_global.php b/modules/turnero/api/get_display_global.php index c5ff09c..ecc0daf 100644 --- a/modules/turnero/api/get_display_global.php +++ b/modules/turnero/api/get_display_global.php @@ -12,33 +12,86 @@ requireMethod('GET'); $pdo = db(); $sesionId = obtenerOCrearSesionHoy(); -// ── 1. TODOS los turnos activos en Recepción ───────────────── -// Puede haber varios simultáneos (un escritorio por operador). -$stmtRec = $pdo->prepare( - "SELECT t.id, - t.codigo, - t.numero, - t.estado, - t.paciente_nombre, - t.llamado_recepcion_at AS llamado_at, - t.atendido_recepcion_por, - 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" +// ── 1. Escritorios de Recepción activos + su turno en_recepcion ─ +// Cada escritorio puede tener un turno distinto (varios recepcionistas). +$stmtDesks = $pdo->query( + "SELECT id, nombre, sort_order + FROM turnero_lugares + WHERE activo = 1 AND tipo = 'recepcion' + ORDER BY sort_order ASC" ); -$stmtRec->execute([$sesionId]); -$activosRecepcion = $stmtRec->fetchAll(PDO::FETCH_ASSOC); +$escritoriosRec = $stmtDesks->fetchAll(PDO::FETCH_ASSOC); -// ── 2. Lugares activos con su turno en servicio ─────────────── +$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.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.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 + WHERE activo = 1 AND (tipo = 'muestras' OR tipo IS NULL) ORDER BY sort_order ASC" ); $lugares = $stmtLugares->fetchAll(PDO::FETCH_ASSOC); @@ -122,8 +175,8 @@ $stats = $stmtStats->fetch(PDO::FETCH_ASSOC); jsonOk([ 'sesion_id' => $sesionId, - 'activos_recepcion'=> $activosRecepcion, // array — todos los en_recepcion - 'lugares' => $lugaresActivos, + 'activos_recepcion'=> $activosRecepcion, // array de desks con su turno + 'lugares' => $lugaresActivos, // array de estaciones de muestras 'cola' => $cola, 'stats' => $stats, 'timestamp' => date('c'), diff --git a/modules/turnero/api/save_lugar.php b/modules/turnero/api/save_lugar.php index a4b1fbd..4fd6ea6 100644 --- a/modules/turnero/api/save_lugar.php +++ b/modules/turnero/api/save_lugar.php @@ -46,20 +46,22 @@ $nombre = trim($input['nombre'] ?? ''); $desc = trim($input['descripcion'] ?? ''); $sortOrder = (int)($input['sort_order'] ?? 99); $activo = (int)($input['activo'] ?? 1); +$tipo = in_array($input['tipo'] ?? '', ['recepcion', 'muestras'], true) + ? $input['tipo'] : 'muestras'; if ($nombre === '') jsonError('El nombre es requerido'); if ($sortOrder < 1) jsonError('El orden debe ser mayor a 0'); if ($id) { $stmt = db()->prepare( - 'UPDATE turnero_lugares SET nombre=?, descripcion=?, sort_order=?, activo=? WHERE id=?' + 'UPDATE turnero_lugares SET nombre=?, tipo=?, descripcion=?, sort_order=?, activo=? WHERE id=?' ); - $stmt->execute([$nombre, $desc ?: null, $sortOrder, $activo, $id]); + $stmt->execute([$nombre, $tipo, $desc ?: null, $sortOrder, $activo, $id]); jsonOk(['id' => $id], 'Lugar actualizado'); } else { $stmt = db()->prepare( - 'INSERT INTO turnero_lugares (nombre, descripcion, sort_order, activo) VALUES (?, ?, ?, ?)' + 'INSERT INTO turnero_lugares (nombre, tipo, descripcion, sort_order, activo) VALUES (?, ?, ?, ?, ?)' ); - $stmt->execute([$nombre, $desc ?: null, $sortOrder, $activo]); + $stmt->execute([$nombre, $tipo, $desc ?: null, $sortOrder, $activo]); jsonOk(['id' => (int)db()->lastInsertId()], 'Lugar creado'); } diff --git a/modules/turnero/views/configuracion.php b/modules/turnero/views/configuracion.php index d5ef9d7..aef9685 100644 --- a/modules/turnero/views/configuracion.php +++ b/modules/turnero/views/configuracion.php @@ -166,15 +166,24 @@ $tab = $_GET['tab'] ?? 'lugares'; - -

Estaciones de servicio configurables

+ ($l['tipo'] ?? 'muestras') === 'recepcion')); + $lugaresMues = array_values(array_filter($lugares, fn($l) => ($l['tipo'] ?? 'muestras') === 'muestras')); + ?> -
- + +
+ +

Escritorios de Recepción

+ +
+

Cada escritorio es una ventanilla donde un recepcionista atiende pacientes. Aparecerá en la columna izquierda de la pantalla TV global.

+ +
+
- - - + + @@ -182,10 +191,7 @@ $tab = $_GET['tab'] ?? 'lugares'; - -
- -

No hay lugares configurados

+ +

No hay escritorios de recepción configurados

-
-

Agregar lugar

+
+

Agregar escritorio de recepción

-
+
- +
- +
-
+
- +
- +
+
+
+ +
+ + +
+ +

Estaciones de Toma de Muestras

+ +
+

Cada estación es donde se toman muestras o se realizan pruebas. Aparecerá en la columna derecha de la pantalla TV global.

+ +
+ +
+ + + + + + + + + + + + +
+ + +

No hay estaciones de muestras configuradas

+ +
+ +
+

Agregar estación de toma de muestras

+
+
+ + +
+
+ + +
+
+ + +
+
+
@@ -226,11 +293,12 @@ $tab = $_GET['tab'] ?? 'lugares';