fix: load desk consents automatically when a turno is opened

- cargarConsentimientosDesk() called from abrirFicha using DESK_ID
- First checks existing DB records (get_consentimientos), falls back to desk config
- abrirFormularioLugar shows proper errors if no patient or no turno
- Starts polling on open to detect patient signature in real time
- Fix creado_at column error in create_consent_token INSERT

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-06-16 11:20:22 -05:00
co-authored by Claude Haiku 4.5
parent 5b02be6686
commit d8a6581fe5
2 changed files with 61 additions and 15 deletions
+2 -2
View File
@@ -60,8 +60,8 @@ if ($existente) {
); );
$stmt = $pdo->prepare( $stmt = $pdo->prepare(
"INSERT INTO turnero_consentimientos (turno_id, formulario_id, token, estado, creado_at) "INSERT INTO turnero_consentimientos (turno_id, formulario_id, token, estado)
VALUES (?, ?, ?, 'pendiente', NOW())" VALUES (?, ?, ?, 'pendiente')"
); );
$stmt->execute([$turnoId, $formularioId, $token]); $stmt->execute([$turnoId, $formularioId, $token]);
} }
+59 -13
View File
@@ -506,8 +506,9 @@ async function onLugarChange() {
} }
} }
async function abrirFormularioLugar(formularioId, nombre) { async function abrirFormularioLugar(formularioId, nombre) {
if (!turnoActivo) return; if (!turnoActivo) { mostrarError('Llama un turno primero.'); return; }
// Si ya hay solicitud guardada, usa el consent token if (!pacienteActivo) { mostrarError('Vincula el paciente antes de abrir el consentimiento.'); return; }
try { try {
const res = await fetch(API + 'create_consent_token.php', { const res = await fetch(API + 'create_consent_token.php', {
method: 'POST', method: 'POST',
@@ -515,13 +516,17 @@ async function abrirFormularioLugar(formularioId, nombre) {
body: JSON.stringify({ turno_id: turnoActivo.id, formulario_id: formularioId }), body: JSON.stringify({ turno_id: turnoActivo.id, formulario_id: formularioId }),
}); });
const json = await res.json(); const json = await res.json();
if (json.ok && json.data?.url) { if (json.ok && (json.data?.url || json.url)) {
window.open(json.data.url, '_blank'); window.open(json.data?.url || json.url, '_blank');
// Polling automático para detectar la firma
if (!pollingConsentimientosId) {
pollingConsentimientosId = setInterval(refrescarConsentimientosLugar, 3000);
}
} else { } else {
window.open('<?= BASE_URL ?>lab_formularios.php', '_blank'); mostrarError(json.error || 'No se pudo generar el enlace de firma.');
} }
} catch (_) { } catch (err) {
window.open('<?= BASE_URL ?>lab_formularios.php', '_blank'); mostrarError('Error al generar enlace: ' + err.message);
} }
} }
@@ -709,15 +714,56 @@ function abrirFicha(turno) {
.catch(() => {}); .catch(() => {});
} }
// Buscar consentimientos si ya tiene solicitud // Cargar consentimientos del desk actual para este turno
verificarSolicitudExistente(turno.id); if (DESK_ID) cargarConsentimientosDesk(turno.id);
} }
async function verificarSolicitudExistente(turnoId) { // ── Cargar consentimientos del desk para el turno ─────────────
async function cargarConsentimientosDesk(turnoId) {
const sec = document.getElementById('sec-consentimientos');
const lista = document.getElementById('lista-consentimientos');
try { try {
const res = await fetch(API + 'get_cola.php?area=recepcion'); // 1. Si el turno ya tiene registros creados, mostrarlos con su estado real
// La solicitud se carga solo después de guardar const resExist = await fetch(`${API}get_consentimientos.php?turno_id=${turnoId}`);
} catch (_) {} const jsonExist = await resExist.json();
if (jsonExist.ok && jsonExist.consentimientos?.length) {
consentimientos = jsonExist.consentimientos.map(c => ({
...c,
formulario_nombre: c.formulario_nombre || c.nombre,
}));
renderConsentimientos(consentimientos);
sec.style.display = '';
return;
}
// 2. Aún no existen registros: mostrar los configurados para el desk como pendientes
const resDesk = await fetch(`${API}get_lugar_formularios.php?lugar_id=${DESK_ID}`);
const jsonDesk = await resDesk.json();
if (!jsonDesk.ok || !jsonDesk.formularios?.length) {
sec.style.display = 'none';
return;
}
lista.innerHTML = jsonDesk.formularios.map(f => {
const nom = escHtml(f.nombre);
return `<div class="consent-item pendiente">
<i class="fas fa-file-signature"></i>
<span class="c-nom">${nom}</span>
<span class="c-badge">Pendiente</span>
<div class="consent-acciones">
<button class="btn btn-outline-primary"
onclick="abrirFormularioLugar(${f.id}, '${nom.replace(/'/g, "\\'")}')"
title="Abrir formulario en nueva pestaña">
<i class="fas fa-external-link-alt"></i> Firmar
</button>
</div>
</div>`;
}).join('');
sec.style.display = '';
} catch (_) {
sec.style.display = 'none';
}
} }
// ── Buscador de paciente ────────────────────────────────────── // ── Buscador de paciente ──────────────────────────────────────