From 076fae78570ecca98858dcd77d0255beadc946ef Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Wed, 22 Apr 2026 09:03:43 -0500 Subject: [PATCH] up --- ...20260422_turnero_lugar_consentimientos.sql | 19 +++++++ modules/turnero/api/save_lugar.php | 52 +++++++++++++----- modules/turnero/api/send_consentimiento.php | 32 ++++++++++- modules/turnero/views/configuracion.php | 53 ++++++++++++++++++- modules/turnero/views/kiosko.php | 36 ++++++++++++- 5 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 migrations/20260422_turnero_lugar_consentimientos.sql diff --git a/migrations/20260422_turnero_lugar_consentimientos.sql b/migrations/20260422_turnero_lugar_consentimientos.sql new file mode 100644 index 0000000..c677dc4 --- /dev/null +++ b/migrations/20260422_turnero_lugar_consentimientos.sql @@ -0,0 +1,19 @@ +-- ════════════════════════════════════════════════════════════════ +-- Migration 20260422 — Consentimientos por lugar/servicio del turnero +-- Permite asociar formularios de consentimiento directamente a un lugar +-- (p.ej. "Toma de Muestras 2") independientemente de los exámenes. +-- ════════════════════════════════════════════════════════════════ + +CREATE TABLE IF NOT EXISTS turnero_lugar_consentimientos ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + lugar_id INT UNSIGNED NOT NULL COMMENT 'FK turnero_lugares.id', + formulario_id INT UNSIGNED NOT NULL COMMENT 'FK lab_formularios.id', + creado_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_lugar_form (lugar_id, formulario_id), + INDEX idx_lugar (lugar_id), + INDEX idx_form (formulario_id), + CONSTRAINT fk_tlc_lugar FOREIGN KEY (lugar_id) REFERENCES turnero_lugares (id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT fk_tlc_form FOREIGN KEY (formulario_id) REFERENCES lab_formularios (id) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + COMMENT='Formularios de consentimiento que aplican para todo turno en un lugar/servicio dado'; diff --git a/modules/turnero/api/save_lugar.php b/modules/turnero/api/save_lugar.php index 4fd6ea6..78aac38 100644 --- a/modules/turnero/api/save_lugar.php +++ b/modules/turnero/api/save_lugar.php @@ -18,6 +18,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $row->execute([$id]); $data = $row->fetch(PDO::FETCH_ASSOC); if (!$data) jsonError('Lugar no encontrado', 404); + // Incluir formularios de consentimiento vinculados + $stmtFc = db()->prepare('SELECT formulario_id FROM turnero_lugar_consentimientos WHERE lugar_id = ?'); + $stmtFc->execute([$id]); + $data['formulario_ids'] = $stmtFc->fetchAll(PDO::FETCH_COLUMN); jsonOk(['data' => $data]); } @@ -48,20 +52,44 @@ $sortOrder = (int)($input['sort_order'] ?? 99); $activo = (int)($input['activo'] ?? 1); $tipo = in_array($input['tipo'] ?? '', ['recepcion', 'muestras'], true) ? $input['tipo'] : 'muestras'; +$formularioIds = isset($input['formulario_ids']) && is_array($input['formulario_ids']) + ? array_filter(array_map('intval', $input['formulario_ids']), fn($v) => $v > 0) + : []; 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=?, tipo=?, descripcion=?, sort_order=?, activo=? WHERE id=?' - ); - $stmt->execute([$nombre, $tipo, $desc ?: null, $sortOrder, $activo, $id]); - jsonOk(['id' => $id], 'Lugar actualizado'); -} else { - $stmt = db()->prepare( - 'INSERT INTO turnero_lugares (nombre, tipo, descripcion, sort_order, activo) VALUES (?, ?, ?, ?, ?)' - ); - $stmt->execute([$nombre, $tipo, $desc ?: null, $sortOrder, $activo]); - jsonOk(['id' => (int)db()->lastInsertId()], 'Lugar creado'); +$pdo = db(); +$pdo->beginTransaction(); +try { + if ($id) { + $stmt = $pdo->prepare( + 'UPDATE turnero_lugares SET nombre=?, tipo=?, descripcion=?, sort_order=?, activo=? WHERE id=?' + ); + $stmt->execute([$nombre, $tipo, $desc ?: null, $sortOrder, $activo, $id]); + $lugarId = $id; + } else { + $stmt = $pdo->prepare( + 'INSERT INTO turnero_lugares (nombre, tipo, descripcion, sort_order, activo) VALUES (?, ?, ?, ?, ?)' + ); + $stmt->execute([$nombre, $tipo, $desc ?: null, $sortOrder, $activo]); + $lugarId = (int) $pdo->lastInsertId(); + } + + // Sincronizar formularios de consentimiento + $pdo->prepare('DELETE FROM turnero_lugar_consentimientos WHERE lugar_id = ?')->execute([$lugarId]); + if (!empty($formularioIds)) { + $stmtIns = $pdo->prepare( + 'INSERT IGNORE INTO turnero_lugar_consentimientos (lugar_id, formulario_id) VALUES (?, ?)' + ); + foreach ($formularioIds as $fid) { + $stmtIns->execute([$lugarId, $fid]); + } + } + + $pdo->commit(); + jsonOk(['id' => $lugarId], $id ? 'Lugar actualizado' : 'Lugar creado'); +} catch (\Throwable $e) { + $pdo->rollBack(); + jsonError('Error al guardar lugar: ' . $e->getMessage(), 500); } diff --git a/modules/turnero/api/send_consentimiento.php b/modules/turnero/api/send_consentimiento.php index 6aac386..d3bd0b0 100644 --- a/modules/turnero/api/send_consentimiento.php +++ b/modules/turnero/api/send_consentimiento.php @@ -38,6 +38,7 @@ $stmt = $pdo->prepare( t.estado, s.id AS solicitud_id, s.paciente_id, + s.lugar_id, p.telefono AS pac_telefono, p.telefono AS pac_celular, p.nombre_completo AS pac_nombre @@ -77,6 +78,7 @@ if (empty($examIds)) { } // ── 3. Obtener formularios de consentimiento (deduplicados) ─── +// 3a. Consentimientos por tipo de examen $in = implode(',', array_fill(0, count($examIds), '?')); $stmt = $pdo->prepare( "SELECT DISTINCT etc.formulario_id, f.nombre AS formulario_nombre @@ -87,8 +89,36 @@ $stmt = $pdo->prepare( $stmt->execute($examIds); $formulariosRequeridos = $stmt->fetchAll(PDO::FETCH_ASSOC); +// 3b. Consentimientos por lugar/servicio (de la solicitud) +$lugarIdSol = (int)($turno['lugar_id'] ?? 0); +if (!$lugarIdSol) { + // Intentar leer lugar_id directo de la solicitud si no vino en el join anterior + $stmtLugar = $pdo->prepare("SELECT lugar_id FROM turnero_solicitudes WHERE id = ?"); + $stmtLugar->execute([$turno['solicitud_id']]); + $lugarIdSol = (int)($stmtLugar->fetchColumn() ?: 0); +} +if ($lugarIdSol > 0) { + $stmtLc = $pdo->prepare( + "SELECT tlc.formulario_id, f.nombre AS formulario_nombre + FROM turnero_lugar_consentimientos tlc + JOIN lab_formularios f ON f.id = tlc.formulario_id + WHERE tlc.lugar_id = ?" + ); + $stmtLc->execute([$lugarIdSol]); + foreach ($stmtLc->fetchAll(PDO::FETCH_ASSOC) as $row) { + // Deduplicar: solo agregar si aún no está en la lista + $yaExiste = false; + foreach ($formulariosRequeridos as $fr) { + if ((int)$fr['formulario_id'] === (int)$row['formulario_id']) { $yaExiste = true; break; } + } + if (!$yaExiste) { + $formulariosRequeridos[] = $row; + } + } +} + if (empty($formulariosRequeridos)) { - jsonOk(['consentimientos' => [], 'mensaje' => 'Ningún examen requiere consentimiento.']); + jsonOk(['consentimientos' => [], 'mensaje' => 'Ningún examen ni servicio requiere consentimiento.']); } // ── 4. Generar / recuperar tokens UUID ──────────────────────── diff --git a/modules/turnero/views/configuracion.php b/modules/turnero/views/configuracion.php index 13bc249..0b3ae1f 100644 --- a/modules/turnero/views/configuracion.php +++ b/modules/turnero/views/configuracion.php @@ -29,7 +29,16 @@ try { $lugares = $pdo->query( 'SELECT * FROM turnero_lugares ORDER BY sort_order ASC, id ASC' )->fetchAll(PDO::FETCH_ASSOC); -} catch (\Throwable $e) { $_loadErrors[] = 'turnero_lugares: ' . $e->getMessage(); } + // Cargar formularios de consentimiento vinculados a cada lugar + $lugarFormIds = []; + foreach ($lugares as $lu) { + $stmtLcf = $pdo->prepare( + "SELECT formulario_id FROM turnero_lugar_consentimientos WHERE lugar_id = ?" + ); + $stmtLcf->execute([$lu['id']]); + $lugarFormIds[(int)$lu['id']] = $stmtLcf->fetchAll(PDO::FETCH_COLUMN); + } +} catch (\Throwable $e) { $_loadErrors[] = 'turnero_lugares: ' . $e->getMessage(); $lugarFormIds = []; } try { $prioridades = $pdo->query( @@ -321,6 +330,28 @@ $tab = $_GET['tab'] ?? 'lugares'; +
+ +
+ +
+ + +
+ + + No hay formularios activos configurados. + +
+