From afa7cc6812cd88a4488898311b23b1ec7b69f904 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 28 Jul 2026 07:49:06 -0500 Subject: [PATCH] feat(turnero): anexar formulario adicional a turno desde lugar.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Permite al operador agregar un consentimiento informado extra (fuera de los asignados por defecto) mientras el turno está en servicio. - PHP: consulta lab_formularios activos al cargar lugar.php - JS: modal de selección con lista de formularios - Botón visible solo cuando turno está en_servicio, oculto en resetFicha - API: modules/turnero/api/anexar_formulario.php crea el consentimiento y notifica SSE para que el dispositivo lo vea inmediatamente - Fix: _olvidarConsentimiento usaba cargarConsentimientos() inexistente; corregido a actualizarConsentimientos(turnoActivo.id) Co-Authored-By: Claude Sonnet 4.6 --- modules/turnero/api/anexar_formulario.php | 43 +++++++++++++ modules/turnero/views/lugar.php | 73 ++++++++++++++++++++++- 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 modules/turnero/api/anexar_formulario.php diff --git a/modules/turnero/api/anexar_formulario.php b/modules/turnero/api/anexar_formulario.php new file mode 100644 index 0000000..2a4f355 --- /dev/null +++ b/modules/turnero/api/anexar_formulario.php @@ -0,0 +1,43 @@ +prepare("SELECT id, sesion_id, estado FROM turnero_turnos WHERE id = ? LIMIT 1"); +$turno->execute([$turnoId]); +$t = $turno->fetch(PDO::FETCH_ASSOC); +if (!$t) jsonError('Turno no encontrado.', 404); +if (!in_array($t['estado'], ['en_espera_lugar', 'en_servicio'])) jsonError('El turno no está activo.'); + +// Verificar que el formulario existe +$form = $pdo->prepare("SELECT id, nombre FROM lab_formularios WHERE id = ? AND is_active = 1 LIMIT 1"); +$form->execute([$formularioId]); +if (!$form->fetch()) jsonError('Formulario no encontrado o inactivo.', 404); + +// Crear el consentimiento con token único +$token = bin2hex(random_bytes(16)); + +$ins = $pdo->prepare( + "INSERT INTO turnero_consentimientos (turno_id, formulario_id, token, estado, datos_respuestas) + VALUES (?, ?, ?, 'enviado', '{}')" +); +$ins->execute([$turnoId, $formularioId, $token]); +$newId = (int)$pdo->lastInsertId(); + +notificarSSE((int)$t['sesion_id']); +jsonOk(['id' => $newId, 'token' => $token], 'Formulario agregado.'); diff --git a/modules/turnero/views/lugar.php b/modules/turnero/views/lugar.php index cd5af58..fe0f631 100644 --- a/modules/turnero/views/lugar.php +++ b/modules/turnero/views/lugar.php @@ -92,6 +92,13 @@ foreach ($lugares as $_el) { $especialidades[] = $_el; } } + +$formulariosList = []; +try { + $formulariosList = Database::getInstance()->getConnection() + ->query("SELECT id, nombre FROM lab_formularios WHERE is_active = 1 ORDER BY nombre ASC") + ->fetchAll(PDO::FETCH_ASSOC); +} catch (\Throwable $_) {} ?> @@ -836,6 +843,11 @@ require_once __DIR__ . '/../../../shared/components/sidebar.php'; +
+ +
@@ -1027,6 +1039,7 @@ let _tomaProgresivaActiva = false; let hayMuestrasPendientes = false; let _solicitudActiva = null; let _muestrasActivas = []; +const _formulariosList = ; const API = 'modules/turnero/api/'; const BASE_WA = ''; @@ -1667,7 +1680,7 @@ async function _olvidarConsentimiento(token, nombre) { }); const j = await r.json(); if (!j.ok) { mostrarError(j.error || 'Error al resetear'); return; } - cargarConsentimientos(); + if (turnoActivo?.id) actualizarConsentimientos(turnoActivo.id); } catch(e) { mostrarError(e.message); } } @@ -2061,10 +2074,45 @@ function resetFicha() { document.getElementById('btn-regresar').classList.add('d-none'); document.getElementById('btn-rellamar').classList.add('d-none'); document.getElementById('btn-devolver').classList.add('d-none'); + document.getElementById('btn-anexar-wrap')?.classList.add('d-none'); volverACola(); } +// ── Anexar formulario ───────────────────────────────────────── +function _abrirAnexarFormulario() { + const sel = document.getElementById('sel-anexar-form'); + sel.innerHTML = ''; + _formulariosList.forEach(f => { + const o = document.createElement('option'); + o.value = f.id; o.textContent = f.nombre; + sel.appendChild(o); + }); + document.getElementById('anexar-form-msg').style.display = 'none'; + document.getElementById('btn-guardar-anexar').disabled = false; + document.getElementById('modal-anexar-form').style.display = 'flex'; +} +function _cerrarAnexarFormulario() { + document.getElementById('modal-anexar-form').style.display = 'none'; +} +async function _guardarAnexarFormulario() { + const fId = parseInt(document.getElementById('sel-anexar-form').value); + const msg = document.getElementById('anexar-form-msg'); + if (!fId) { msg.textContent = 'Selecciona un formulario.'; msg.style.display=''; return; } + const btn = document.getElementById('btn-guardar-anexar'); + btn.disabled = true; + try { + const r = await fetch('modules/turnero/api/anexar_formulario.php', { + method: 'POST', headers: {'Content-Type':'application/json'}, + body: JSON.stringify({ turno_id: turnoActivo.id, formulario_id: fId }) + }); + const j = await r.json(); + if (!j.ok) { msg.textContent = j.error || 'Error al agregar.'; msg.style.display=''; btn.disabled=false; return; } + _cerrarAnexarFormulario(); + actualizarConsentimientos(turnoActivo.id); + } catch(e) { msg.textContent = e.message; msg.style.display=''; btn.disabled=false; } +} + // ── Mobile ──────────────────────────────────────────────────── function esMobile() { return window.innerWidth <= 680; } @@ -2099,6 +2147,7 @@ function actualizarEstadoBadge(estado) { const btnDev = document.getElementById('btn-devolver'); const btnEsp = document.getElementById('btn-espera'); + const btnAnexar = document.getElementById('btn-anexar-wrap'); if (estado === 'en_espera_lugar') { btnIni.classList.remove('d-none'); btnIni.disabled = false; btnFin.classList.add('d-none'); @@ -2106,6 +2155,7 @@ function actualizarEstadoBadge(estado) { btnRellamar.classList.add('d-none'); btnDev.classList.remove('d-none'); if (btnEsp) btnEsp.classList.add('d-none'); + if (btnAnexar) btnAnexar.classList.add('d-none'); } else if (estado === 'en_servicio') { btnIni.classList.add('d-none'); btnFin.classList.remove('d-none'); @@ -2114,6 +2164,7 @@ function actualizarEstadoBadge(estado) { btnDev.classList.remove('d-none'); // btn-espera: solo si hay toma progresiva activa (sincronizado desde renderConsentimientos) if (btnEsp) btnEsp.classList.add('d-none'); + if (btnAnexar) btnAnexar.classList.remove('d-none'); } } @@ -2864,6 +2915,26 @@ function _renderEspecialidades(grupos) { })(); + + +