up
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
-- ============================================================
|
||||
-- Migration: 20260611_turnero_consentimiento_principal
|
||||
-- Añade flag is_principal a lab_formularios para marcar
|
||||
-- el consentimiento principal de recepción (no ligado a exámenes).
|
||||
-- ============================================================
|
||||
|
||||
ALTER TABLE lab_formularios
|
||||
ADD COLUMN is_principal TINYINT(1) NOT NULL DEFAULT 0
|
||||
COMMENT '1 = consentimiento principal de recepción, se auto-crea al tomar turno'
|
||||
AFTER tipo;
|
||||
@@ -0,0 +1,13 @@
|
||||
-- ============================================================
|
||||
-- Migration: 20260611_turnero_paciente_id
|
||||
-- Añade paciente_id (FK lab_pacientes) a turnero_turnos
|
||||
-- para que el paciente quede vinculado desde el kiosko.
|
||||
-- ============================================================
|
||||
|
||||
ALTER TABLE turnero_turnos
|
||||
ADD COLUMN paciente_id INT(11) DEFAULT NULL
|
||||
COMMENT 'FK lab_pacientes.id (vinculado desde kiosko o recepción)'
|
||||
AFTER paciente_cel;
|
||||
|
||||
ALTER TABLE turnero_turnos
|
||||
ADD INDEX idx_paciente_id (paciente_id);
|
||||
@@ -24,9 +24,9 @@ if (!in_array($prioCodigo, ['A', 'B', 'C', 'D', 'E', 'F'], true)) {
|
||||
jsonError('prioridad_codigo inválido. Use A, B, C, D, E o F.');
|
||||
}
|
||||
|
||||
$pacienteNombre = substr(trim($datos['paciente_nombre'] ?? ''), 0, 150);
|
||||
$pacienteCel = preg_replace('/[^0-9+\- ]/', '', $datos['paciente_cel'] ?? '');
|
||||
$pacienteCel = substr($pacienteCel, 0, 20);
|
||||
$pacienteDoc = substr(trim($datos['paciente_nombre'] ?? ''), 0, 150);
|
||||
$pacienteCel = preg_replace('/[^0-9+\- ]/', '', $datos['paciente_cel'] ?? '');
|
||||
$pacienteCel = substr($pacienteCel, 0, 20);
|
||||
|
||||
// ── Lógica principal (dentro de transacción para evitar race conditions) ──
|
||||
$pdo = db();
|
||||
@@ -49,6 +49,27 @@ try {
|
||||
|
||||
$prioridadId = (int) $prioridad['id'];
|
||||
|
||||
// Buscar paciente por número de documento en lab_pacientes
|
||||
$pacienteNombre = $pacienteDoc;
|
||||
$pacienteId = null;
|
||||
$pacienteTel = $pacienteCel; // fallback: celular del kiosko
|
||||
if ($pacienteDoc) {
|
||||
try {
|
||||
$stmtP = $pdo->prepare(
|
||||
'SELECT id, nombre_completo, telefono FROM lab_pacientes WHERE numero_documento = ? AND is_active = 1 LIMIT 1'
|
||||
);
|
||||
$stmtP->execute([$pacienteDoc]);
|
||||
$pacRow = $stmtP->fetch(PDO::FETCH_ASSOC);
|
||||
if ($pacRow) {
|
||||
$pacienteNombre = $pacRow['nombre_completo'];
|
||||
$pacienteId = (int) $pacRow['id'];
|
||||
$pacienteTel = $pacRow['telefono'] ?: $pacienteCel;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$pacienteNombre = $pacienteDoc;
|
||||
}
|
||||
}
|
||||
|
||||
// Correlativo independiente por prioridad (A-001, A-002... B-001, B-002... etc.)
|
||||
$numero = siguienteNumeroPorPrioridad($sesionId, $prioridadId);
|
||||
|
||||
@@ -57,10 +78,10 @@ try {
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
'INSERT INTO turnero_turnos
|
||||
(sesion_id, numero, codigo, prioridad_id, paciente_nombre, paciente_cel,
|
||||
(sesion_id, numero, codigo, prioridad_id, paciente_nombre, paciente_cel, paciente_id,
|
||||
estado, creado_at)
|
||||
VALUES
|
||||
(?, ?, ?, ?, ?, ?, "espera", NOW())'
|
||||
(?, ?, ?, ?, ?, ?, ?, "espera", NOW())'
|
||||
);
|
||||
$stmt->execute([
|
||||
$sesionId,
|
||||
@@ -69,6 +90,7 @@ try {
|
||||
$prioridadId,
|
||||
$pacienteNombre ?: null,
|
||||
$pacienteCel ?: null,
|
||||
$pacienteId,
|
||||
]);
|
||||
|
||||
$turnoId = (int) $pdo->lastInsertId();
|
||||
@@ -76,6 +98,69 @@ try {
|
||||
|
||||
notificarSSE($sesionId);
|
||||
|
||||
// ── Auto-crear consentimiento principal + enviar WhatsApp ──
|
||||
try {
|
||||
$stmtPc = $pdo->prepare(
|
||||
"SELECT id, nombre FROM lab_formularios WHERE is_principal = 1 AND tipo = 'consentimiento' AND is_active = 1 LIMIT 1"
|
||||
);
|
||||
$stmtPc->execute();
|
||||
$principalForm = $stmtPc->fetch(PDO::FETCH_ASSOC);
|
||||
if ($principalForm) {
|
||||
$tokenPrincipal = sprintf(
|
||||
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000,
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
|
||||
);
|
||||
$stmtIns = $pdo->prepare(
|
||||
"INSERT IGNORE INTO turnero_consentimientos (turno_id, formulario_id, token, estado)
|
||||
VALUES (?, ?, ?, 'pendiente')"
|
||||
);
|
||||
$stmtIns->execute([$turnoId, (int)$principalForm['id'], $tokenPrincipal]);
|
||||
|
||||
// Enviar WhatsApp si tenemos celular
|
||||
if ($pacienteTel) {
|
||||
$cel = preg_replace('/[\s\-\.]/', '', $pacienteTel);
|
||||
if (!str_starts_with($cel, '+')) {
|
||||
$cel = '+57' . ltrim($cel, '0');
|
||||
}
|
||||
$enlaceFirma = (defined('BASE_URL') ? rtrim(BASE_URL, '/') : '')
|
||||
. '/ver_formulario_enviado.php?token=' . urlencode($tokenPrincipal);
|
||||
$nombrePacWA = $pacienteNombre ?: 'Paciente';
|
||||
require_once __DIR__ . '/../../../services/WhatsAppService.php';
|
||||
try {
|
||||
$wa = new WhatsAppService();
|
||||
$wa->sendTemplateMessage(
|
||||
$cel,
|
||||
'consentimiento_turno',
|
||||
'es',
|
||||
[
|
||||
htmlspecialchars($nombrePacWA, ENT_QUOTES),
|
||||
htmlspecialchars($principalForm['nombre'], ENT_QUOTES),
|
||||
$codigo,
|
||||
],
|
||||
[$enlaceFirma]
|
||||
);
|
||||
} catch (\Throwable $eTmpl) {
|
||||
try {
|
||||
$mensajeTexto = "Hola {$nombrePacWA}, le informamos que para su turno *{$codigo}* "
|
||||
. "debe firmar el siguiente consentimiento informado:\n\n"
|
||||
. "*{$principalForm['nombre']}*\n\n"
|
||||
. "Puede firmarlo en el siguiente enlace:\n{$enlaceFirma}\n\n"
|
||||
. "Si ya firmó este documento presencial, ignore este mensaje.";
|
||||
$wa->sendTextMessage($cel, $mensajeTexto);
|
||||
} catch (\Throwable $eTxt) {
|
||||
// Silenciar error de WhatsApp, el turno ya se creó
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Silenciar error — el turno ya se creó exitosamente
|
||||
}
|
||||
|
||||
// Contar posición en la cola
|
||||
$stmt = $pdo->prepare(
|
||||
'
|
||||
|
||||
@@ -117,6 +117,28 @@ if ($lugarIdSol > 0) {
|
||||
}
|
||||
}
|
||||
|
||||
// 3c. Consentimiento principal de recepción (is_principal)
|
||||
$principalRow = null;
|
||||
try {
|
||||
$stmtPc = $pdo->prepare(
|
||||
"SELECT id AS formulario_id, nombre AS formulario_nombre
|
||||
FROM lab_formularios
|
||||
WHERE is_principal = 1 AND tipo = 'consentimiento' AND is_active = 1
|
||||
LIMIT 1"
|
||||
);
|
||||
$stmtPc->execute();
|
||||
$principalRow = $stmtPc->fetch(PDO::FETCH_ASSOC);
|
||||
} catch (\Throwable $e) {}
|
||||
if ($principalRow) {
|
||||
$yaExiste = false;
|
||||
foreach ($formulariosRequeridos as $fr) {
|
||||
if ((int)$fr['formulario_id'] === (int)$principalRow['formulario_id']) { $yaExiste = true; break; }
|
||||
}
|
||||
if (!$yaExiste) {
|
||||
$formulariosRequeridos[] = $principalRow;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($formulariosRequeridos)) {
|
||||
jsonOk(['consentimientos' => [], 'mensaje' => 'Ningún examen ni servicio requiere consentimiento.']);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* modules/turnero/api/set_principal_consent.php
|
||||
* POST { formulario_id: int | null }
|
||||
* Marca un lab_formularios como consentimiento principal de recepción.
|
||||
* Pasa null para desmarcar (ningún principal).
|
||||
* Solo UN formulario puede ser principal a la vez.
|
||||
*/
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
requireTurnero();
|
||||
|
||||
$input = inputJson();
|
||||
$formularioId = isset($input['formulario_id']) ? (int) $input['formulario_id'] : null;
|
||||
|
||||
$pdo = db();
|
||||
|
||||
if ($formularioId) {
|
||||
// Verificar que el formulario existe y es tipo consentimiento
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT id FROM lab_formularios WHERE id = ? AND tipo = 'consentimiento' AND is_active = 1"
|
||||
);
|
||||
$stmt->execute([$formularioId]);
|
||||
if (!$stmt->fetch()) {
|
||||
jsonError('Formulario no encontrado o no es un consentimiento activo.', 404);
|
||||
}
|
||||
}
|
||||
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
// Quitar principal de todos
|
||||
$pdo->exec("UPDATE lab_formularios SET is_principal = 0 WHERE is_principal = 1");
|
||||
// Marcar el nuevo principal (si aplica)
|
||||
if ($formularioId) {
|
||||
$stmt = $pdo->prepare("UPDATE lab_formularios SET is_principal = 1 WHERE id = ?");
|
||||
$stmt->execute([$formularioId]);
|
||||
}
|
||||
$pdo->commit();
|
||||
jsonOk([
|
||||
'formulario_id' => $formularioId,
|
||||
], $formularioId ? 'Consentimiento principal actualizado' : 'Consentimiento principal desmarcado');
|
||||
} catch (\Throwable $e) {
|
||||
$pdo->rollBack();
|
||||
jsonError('Error al actualizar: ' . $e->getMessage(), 500);
|
||||
}
|
||||
@@ -58,7 +58,7 @@ try {
|
||||
|
||||
try {
|
||||
$formulariosCons = $pdo->query(
|
||||
"SELECT id, nombre FROM lab_formularios WHERE is_active=1 ORDER BY nombre ASC"
|
||||
"SELECT id, nombre, COALESCE(is_principal,0) AS is_principal FROM lab_formularios WHERE is_active=1 ORDER BY nombre ASC"
|
||||
)->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (\Throwable $e) { $_loadErrors[] = 'lab_formularios: ' . $e->getMessage(); }
|
||||
|
||||
@@ -491,16 +491,37 @@ $tab = $_GET['tab'] ?? 'lugares';
|
||||
<?php if (!empty($formulariosCons)): ?>
|
||||
<div class="mt-4">
|
||||
<p class="section-title"><i class="fas fa-file-signature me-1"></i>Vista inversa: por consentimiento</p>
|
||||
|
||||
<div class="alert alert-info py-2 px-3 small mb-3" style="font-size:.8rem">
|
||||
<i class="fas fa-star me-1 text-warning"></i>
|
||||
Marque un consentimiento como <strong>principal</strong> (el que se firma en recepción para pasar a toma de muestras).
|
||||
Se auto-creará cuando el paciente tome turno en el kiosko y se enviará por WhatsApp automáticamente.
|
||||
</div>
|
||||
|
||||
<?php $principalEncontrado = false; ?>
|
||||
<?php foreach ($formulariosCons as $fc):
|
||||
$exsVinculados = [];
|
||||
foreach ($examTipos as $et) {
|
||||
$fids = $et['form_ids'] ? array_map('intval', explode(',', $et['form_ids'])) : [];
|
||||
if (in_array((int)$fc['id'], $fids)) $exsVinculados[] = $et;
|
||||
}
|
||||
$esPrincipal = !empty($fc['is_principal']);
|
||||
if ($esPrincipal) $principalEncontrado = true;
|
||||
?>
|
||||
<div class="mb-2">
|
||||
<div class="mb-2 d-flex align-items-center gap-2" style="padding:4px 0">
|
||||
<?php if ($esPrincipal): ?>
|
||||
<span class="badge bg-warning text-dark" style="font-size:.65rem;cursor:pointer"
|
||||
onclick="quitarPrincipalConsent(<?= (int)$fc['id'] ?>)" title="Quitar como principal">
|
||||
<i class="fas fa-star"></i> Principal
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-light text-muted" style="font-size:.65rem;cursor:pointer"
|
||||
onclick="marcarPrincipalConsent(<?= (int)$fc['id'] ?>)" title="Marcar como consentimiento principal">
|
||||
<i class="far fa-star"></i>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<span class="fw-semibold small"><?= htmlspecialchars($fc['nombre']) ?></span>
|
||||
<span class="text-muted small ms-2">
|
||||
<span class="text-muted small ms-1">
|
||||
<?= empty($exsVinculados)
|
||||
? '<em>Sin exámenes vinculados</em>'
|
||||
: implode(', ', array_map(fn($e)=>'<code>'.$e['codigo'].'</code>', $exsVinculados))
|
||||
@@ -508,6 +529,11 @@ $tab = $_GET['tab'] ?? 'lugares';
|
||||
</span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php if (!$principalEncontrado): ?>
|
||||
<div class="text-muted small">
|
||||
<em>Ningún consentimiento marcado como principal.</em>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -1123,6 +1149,32 @@ async function borrarTvVideo() {
|
||||
} catch(e) { toast('Error de conexión', 'error'); }
|
||||
}
|
||||
|
||||
// ── Consentimiento principal ──────────────────────────────────
|
||||
async function marcarPrincipalConsent(formularioId) {
|
||||
try {
|
||||
const res = await fetch(API + 'set_principal_consent.php', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ formulario_id: formularioId })
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!json.ok) { toast(json.error || 'Error', 'error'); return; }
|
||||
toast('Consentimiento principal actualizado');
|
||||
setTimeout(() => location.reload(), 400);
|
||||
} catch (e) { toast('Error de conexión', 'error'); }
|
||||
}
|
||||
async function quitarPrincipalConsent() {
|
||||
try {
|
||||
const res = await fetch(API + 'set_principal_consent.php', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ formulario_id: null })
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!json.ok) { toast(json.error || 'Error', 'error'); return; }
|
||||
toast('Consentimiento principal desmarcado');
|
||||
setTimeout(() => location.reload(), 400);
|
||||
} catch (e) { toast('Error de conexión', 'error'); }
|
||||
}
|
||||
|
||||
async function guardarWhatsApp() {
|
||||
const template = document.getElementById('wa-template')?.value.trim();
|
||||
const lang = document.getElementById('wa-lang')?.value.trim();
|
||||
|
||||
@@ -108,17 +108,10 @@ $_hasVideo = (bool)$_tvVideo;
|
||||
position: relative;
|
||||
}
|
||||
.pg-body.has-video {
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-columns: 240px 1fr 240px;
|
||||
}
|
||||
|
||||
|
||||
/* ── Left area ── */
|
||||
.left-area {
|
||||
display: flex; flex-direction: column;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* ── Turno activo (centro) ── */
|
||||
.turno-activo {
|
||||
display: flex; flex-direction: column;
|
||||
@@ -165,31 +158,44 @@ $_hasVideo = (bool)$_tvVideo;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
/* ── Últimos llamados ── */
|
||||
.ultimos-llamados {
|
||||
flex-shrink: 0;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding: .3rem 1.5rem .5rem;
|
||||
/* ── Últimos llamados (columna izquierda) ── */
|
||||
.left-area {
|
||||
display: flex; flex-direction: column;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-right: 1px solid #e2e8f0;
|
||||
}
|
||||
.ultimos-llamados {
|
||||
display: flex; flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
.ultimos-llamados .ul-label {
|
||||
font-size: .7rem; font-weight: 700; text-transform: uppercase;
|
||||
letter-spacing: 2px; color: #94a3b8; margin-bottom: .2rem;
|
||||
letter-spacing: 2px; color: #94a3b8;
|
||||
padding: .8rem .8rem .3rem; flex-shrink: 0;
|
||||
}
|
||||
.ultimos-llamados .ul-scroll {
|
||||
display: flex; gap: .5rem;
|
||||
overflow-x: auto; scrollbar-width: none;
|
||||
flex: 1; overflow-y: auto; padding: 0 .5rem .5rem;
|
||||
scrollbar-width: thin; scrollbar-color: #e2e8f0 transparent;
|
||||
}
|
||||
.ultimos-llamados .ul-scroll::-webkit-scrollbar { display: none; }
|
||||
.ul-item {
|
||||
display: flex; align-items: center; gap: .4rem;
|
||||
padding: .25rem .7rem; border-radius: 99px;
|
||||
padding: .5rem .6rem; border-radius: 8px;
|
||||
margin-bottom: .25rem;
|
||||
background: #f8fafc; border: 1px solid #e2e8f0;
|
||||
white-space: nowrap; flex-shrink: 0;
|
||||
font-size: .72rem;
|
||||
}
|
||||
.ul-item .ul-cod { font-weight: 800; font-size: .78rem; }
|
||||
.ul-item .ul-nom { font-size: .72rem; color: #64748b; }
|
||||
.ul-item .ul-dest { font-size: .65rem; color: #94a3b8; }
|
||||
.ul-item.activo {
|
||||
background: var(--brand);
|
||||
border-color: var(--brand);
|
||||
color: #fff;
|
||||
}
|
||||
.ul-item.activo .ul-nom,
|
||||
.ul-item.activo .ul-dest { color: rgba(255,255,255,.75); }
|
||||
.ul-item .ul-cod { font-weight: 800; font-size: .82rem; display: block; }
|
||||
.ul-item .ul-nom { color: #1e293b; font-weight: 600; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.ul-item .ul-dest { color: #64748b; font-size: .65rem; display: block; }
|
||||
.ul-item .ul-dest i { margin-right: 2px; }
|
||||
|
||||
/* ── Video reel (9:16, alto completo, columna derecha) ── */
|
||||
@@ -364,18 +370,18 @@ $_hasVideo = (bool)$_tvVideo;
|
||||
|
||||
<div class="pg-body <?= $_hasVideo ? 'has-video' : '' ?>">
|
||||
<div class="left-area">
|
||||
<div class="turno-activo" id="zona-activo">
|
||||
<div class="label">Siguiente turno</div>
|
||||
<div class="codigo" id="codigo-activo">—</div>
|
||||
<div class="lugar-label" id="lugar-label">Llamado a</div>
|
||||
<div class="lugar-nombre" id="lugar-nombre">—</div>
|
||||
<div class="pac-nombre" id="pac-nombre"></div>
|
||||
</div>
|
||||
<div class="ultimos-llamados" id="ultimos-llamados" style="display:none">
|
||||
<div class="ul-label"><i class="fas fa-history me-1"></i>Últimos llamados</div>
|
||||
<div class="ul-label"><i class="fas fa-history me-1"></i>Llamados</div>
|
||||
<div class="ul-scroll" id="ul-scroll"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="turno-activo" id="zona-activo">
|
||||
<div class="label">Siguiente turno</div>
|
||||
<div class="codigo" id="codigo-activo">—</div>
|
||||
<div class="lugar-label" id="lugar-label">Llamado a</div>
|
||||
<div class="lugar-nombre" id="lugar-nombre">—</div>
|
||||
<div class="pac-nombre" id="pac-nombre"></div>
|
||||
</div>
|
||||
<div class="reel-wrap <?= $_hasVideo ? 'has-video' : '' ?>" id="reel-wrap">
|
||||
<div class="reel-inner">
|
||||
<video autoplay muted loop playsinline>
|
||||
@@ -565,7 +571,7 @@ function renderSnapshot(snap) {
|
||||
});
|
||||
lastTurnoKey = key;
|
||||
llamados.unshift({ codigo: t.codigo, destino: t.destino, paciente: t.paciente_nombre, color: c });
|
||||
if (llamados.length > 20) llamados.pop();
|
||||
if (llamados.length > 30) llamados.pop();
|
||||
renderLlamados();
|
||||
}
|
||||
} else {
|
||||
@@ -611,13 +617,16 @@ function renderLlamados() {
|
||||
if (!wrap || !sc) return;
|
||||
if (llamados.length === 0) { wrap.style.display = 'none'; return; }
|
||||
wrap.style.display = '';
|
||||
sc.innerHTML = llamados.map(l => `
|
||||
<div class="ul-item">
|
||||
<span class="ul-cod" style="color:${l.color || '<?= $_labColor ?>'}">${esc(l.codigo)}</span>
|
||||
const activo = llamados[0];
|
||||
sc.innerHTML = llamados.map((l, i) => {
|
||||
const isActivo = i === 0;
|
||||
const c = l.color || '<?= $_labColor ?>';
|
||||
return `<div class="ul-item${isActivo ? ' activo' : ''}"${isActivo ? ' style="--brand:' + c + '"' : ''}>
|
||||
<span class="ul-cod">${esc(l.codigo)}</span>
|
||||
${l.paciente ? `<span class="ul-nom">${esc(l.paciente)}</span>` : ''}
|
||||
<span class="ul-dest"><i class="fas fa-arrow-right"></i> ${esc(l.destino)}</span>
|
||||
</div>
|
||||
`).join('');
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
|
||||
@@ -583,8 +583,32 @@ function abrirFicha(turno) {
|
||||
document.getElementById('btn-guardar').disabled = false;
|
||||
desvincularPaciente();
|
||||
|
||||
// Buscar consentimientos si ya tiene solicitud
|
||||
verificarSolicitudExistente(turno.id);
|
||||
// Auto-vincular paciente si ya viene con ID desde el kiosko
|
||||
if (turno.paciente_id) {
|
||||
fetch(`${API_PAC}?id=${turno.paciente_id}`)
|
||||
.then(r => r.json())
|
||||
.then(json => {
|
||||
const data = (json.data || json.registros || [])[0];
|
||||
if (data && !pacienteActivo) seleccionarPaciente(data);
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
// Cargar consentimientos anticipados (principal y otros ya creados)
|
||||
cargarConsentimientosTurno(turno.id);
|
||||
}
|
||||
|
||||
async function cargarConsentimientosTurno(turnoId) {
|
||||
try {
|
||||
const res = await fetch(`${API}get_consentimientos.php?turno_id=${turnoId}`);
|
||||
const json = await res.json();
|
||||
if (json.ok && json.consentimientos?.length) {
|
||||
consentimientos = json.consentimientos;
|
||||
renderConsentimientos(consentimientos);
|
||||
document.getElementById('sec-consentimientos').style.display = '';
|
||||
document.getElementById('btn-reenviar-consent').classList.remove('d-none');
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
async function verificarSolicitudExistente(turnoId) {
|
||||
|
||||
Reference in New Issue
Block a user