up
This commit is contained in:
@@ -118,7 +118,35 @@ try {
|
||||
|
||||
// Recuperar hash e id para la respuesta
|
||||
$db = Database::getInstance();
|
||||
$saved = $db->fetch('SELECT id, hash_verificacion FROM lab_form_envios WHERE token = ?', [$token]);
|
||||
$saved = $db->fetch('SELECT id, hash_verificacion, turnero_consentimiento_id FROM lab_form_envios WHERE token = ?', [$token]);
|
||||
|
||||
// Si este envío está vinculado a un consentimiento del turnero, marcarlo como firmado
|
||||
if (!empty($saved['turnero_consentimiento_id'])) {
|
||||
$pdo2 = $db->getConnection();
|
||||
$tc = $pdo2->prepare(
|
||||
"SELECT tc.id, t.sesion_id FROM turnero_consentimientos tc
|
||||
JOIN turnero_turnos t ON t.id = tc.turno_id
|
||||
WHERE tc.id = ? AND tc.estado != 'firmado'"
|
||||
);
|
||||
$tc->execute([(int)$saved['turnero_consentimiento_id']]);
|
||||
$tcRow = $tc->fetch(PDO::FETCH_ASSOC);
|
||||
if ($tcRow) {
|
||||
$datosRespuestasJson = !empty($datosCliente)
|
||||
? json_encode($datosCliente, JSON_UNESCAPED_UNICODE)
|
||||
: null;
|
||||
$pdo2->prepare(
|
||||
"UPDATE turnero_consentimientos
|
||||
SET estado='firmado', firmado_at=NOW(), firma_svg=?,
|
||||
ip_firma=?, ua_firma=?, datos_respuestas=?
|
||||
WHERE id=?"
|
||||
)->execute([$firmaSvg, $ip, substr($ua, 0, 500), $datosRespuestasJson, (int)$tcRow['id']]);
|
||||
// Notificar via SSE para actualizar lugar.php en tiempo real
|
||||
if ($tcRow['sesion_id']) {
|
||||
require_once __DIR__ . '/../../modules/turnero/api/_helpers.php';
|
||||
notificarSSE((int)$tcRow['sesion_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pubOk([
|
||||
'firmado' => (bool)$firmaSvg,
|
||||
|
||||
@@ -1088,6 +1088,8 @@ const formCliente = {
|
||||
}
|
||||
show('success-screen');
|
||||
window.scrollTo({top: 0, behavior: 'smooth'});
|
||||
// Notificar al frame padre si estamos en modo presencial del turnero
|
||||
try { window.parent.postMessage({ type: 'turneroFirmado' }, '*'); } catch(_) {}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
-- Vincula lab_form_envios con turnero_consentimientos para firma presencial
|
||||
ALTER TABLE lab_form_envios
|
||||
ADD COLUMN IF NOT EXISTS turnero_consentimiento_id INT UNSIGNED DEFAULT NULL
|
||||
COMMENT 'FK turnero_consentimientos.id cuando es firma presencial del turnero',
|
||||
ADD INDEX IF NOT EXISTS idx_fenv_tc (turnero_consentimiento_id);
|
||||
|
||||
-- Vinculo inverso: el consentimiento sabe cuál lab_form_envios usa para firma presencial
|
||||
ALTER TABLE turnero_consentimientos
|
||||
ADD COLUMN IF NOT EXISTS lab_form_envio_id INT DEFAULT NULL
|
||||
COMMENT 'FK lab_form_envios.id para firma presencial via form_cliente.php';
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* POST /modules/turnero/api/crear_envio_presencial.php
|
||||
*
|
||||
* Crea (o recupera) un registro lab_form_envios vinculado a un turnero_consentimientos
|
||||
* para que el paciente pueda firmar presencialmente via form_cliente.php?t=TOKEN.
|
||||
*
|
||||
* Body JSON:
|
||||
* consent_token string UUID del turnero_consentimientos (requerido)
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
|
||||
$datos = inputJson();
|
||||
$consentToken = trim($datos['consent_token'] ?? '');
|
||||
|
||||
if (!preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $consentToken)) {
|
||||
jsonError('consent_token inválido.');
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
|
||||
// ── 1. Cargar el consentimiento con datos del turno y paciente ────────
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT tc.id AS tc_id,
|
||||
tc.formulario_id,
|
||||
tc.token AS tc_token,
|
||||
tc.estado,
|
||||
tc.lab_form_envio_id,
|
||||
ts.paciente_id,
|
||||
t.sesion_id,
|
||||
p.nombre_completo, p.tipo_documento, p.numero_documento,
|
||||
p.fecha_nacimiento, p.telefono, p.eps
|
||||
FROM turnero_consentimientos tc
|
||||
JOIN turnero_turnos t ON t.id = tc.turno_id
|
||||
LEFT JOIN turnero_solicitudes ts ON ts.turno_id = tc.turno_id
|
||||
LEFT JOIN lab_pacientes p ON p.id = ts.paciente_id
|
||||
WHERE tc.token = ?
|
||||
LIMIT 1"
|
||||
);
|
||||
$stmt->execute([$consentToken]);
|
||||
$tc = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$tc) jsonError('Consentimiento no encontrado.', 404);
|
||||
|
||||
// ── Si ya fue firmado o tiene envío vinculado, devolver ese token ────
|
||||
if ($tc['lab_form_envio_id']) {
|
||||
$stEnv = $pdo->prepare("SELECT token, estado FROM lab_form_envios WHERE id = ?");
|
||||
$stEnv->execute([(int)$tc['lab_form_envio_id']]);
|
||||
$envio = $stEnv->fetch(PDO::FETCH_ASSOC);
|
||||
if ($envio) {
|
||||
// Si el envio no fue completado todavía, reutilizarlo
|
||||
if (!in_array($envio['estado'], ['completado', 'firmado'])) {
|
||||
jsonOk(['form_token' => $envio['token']]);
|
||||
}
|
||||
// Si ya completado, devolver igualmente el token para que el operador lo vea
|
||||
jsonOk(['form_token' => $envio['token'], 'ya_firmado' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($tc['estado'] === 'firmado') {
|
||||
jsonError('Este consentimiento ya fue firmado.', 409);
|
||||
}
|
||||
|
||||
// ── 3. Crear nuevo lab_form_envios ────────────────────────────────────
|
||||
$formToken = bin2hex(random_bytes(32)); // 64 chars hex
|
||||
|
||||
$prefilled = [];
|
||||
if ($tc['nombre_completo']) $prefilled['__paciente']['nombre_completo'] = $tc['nombre_completo'];
|
||||
if ($tc['tipo_documento']) $prefilled['__paciente']['tipo_documento'] = $tc['tipo_documento'];
|
||||
if ($tc['numero_documento']) $prefilled['__paciente']['numero_documento'] = $tc['numero_documento'];
|
||||
if ($tc['fecha_nacimiento']) $prefilled['__paciente']['fecha_nacimiento'] = $tc['fecha_nacimiento'];
|
||||
if ($tc['telefono']) $prefilled['__paciente']['telefono'] = $tc['telefono'];
|
||||
if ($tc['eps']) $prefilled['__paciente']['eps'] = $tc['eps'];
|
||||
|
||||
$userId = (int)($_SESSION['admin_user']['id'] ?? 0) ?: null;
|
||||
|
||||
$ins = $pdo->prepare(
|
||||
"INSERT INTO lab_form_envios
|
||||
(formulario_id, paciente_id, token, datos_prefilled, estado, enviado_por, enviado_via, turnero_consentimiento_id)
|
||||
VALUES (?, ?, ?, ?, 'pendiente', ?, 'link', ?)"
|
||||
);
|
||||
$ins->execute([
|
||||
(int)$tc['formulario_id'],
|
||||
$tc['paciente_id'] ?: null,
|
||||
$formToken,
|
||||
json_encode($prefilled, JSON_UNESCAPED_UNICODE),
|
||||
$userId,
|
||||
(int)$tc['tc_id'],
|
||||
]);
|
||||
|
||||
$formEnvioId = (int)$pdo->lastInsertId();
|
||||
|
||||
// ── 4. Guardar el vínculo en turnero_consentimientos ─────────────────
|
||||
$pdo->prepare("UPDATE turnero_consentimientos SET lab_form_envio_id = ? WHERE id = ?")
|
||||
->execute([$formEnvioId, (int)$tc['tc_id']]);
|
||||
|
||||
jsonOk(['form_token' => $formToken]);
|
||||
@@ -715,14 +715,28 @@ async function reenviarConsentimiento(turnoId) {
|
||||
}
|
||||
|
||||
// ── Modal de firma presencial ─────────────────────────────────
|
||||
function abrirFirmaPresencial(token, consentId, nombreForm) {
|
||||
const url = BASE_WA + 'ver_formulario_enviado.php?token=' + encodeURIComponent(token);
|
||||
document.getElementById('modal-firma-titulo').textContent = 'Firmar: ' + nombreForm;
|
||||
document.getElementById('firma-iframe').src = url;
|
||||
async function abrirFirmaPresencial(token, consentId, nombreForm) {
|
||||
document.getElementById('modal-firma-titulo').textContent = 'Cargando…';
|
||||
document.getElementById('firma-iframe').src = '';
|
||||
document.getElementById('modal-firma').classList.add('open');
|
||||
|
||||
// Al cerrar, refrescar consentimientos
|
||||
window._firmaConsentId = consentId;
|
||||
|
||||
try {
|
||||
const res = await fetch(API + 'crear_envio_presencial.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ consent_token: token }),
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!json.ok || !json.form_token) throw new Error(json.error || 'Error al crear envío');
|
||||
document.getElementById('modal-firma-titulo').textContent = 'Firmar: ' + nombreForm;
|
||||
document.getElementById('firma-iframe').src = BASE_WA + 'form_cliente.php?t=' + encodeURIComponent(json.form_token);
|
||||
} catch (err) {
|
||||
document.getElementById('modal-firma-titulo').textContent = 'Error';
|
||||
document.getElementById('firma-iframe').src = '';
|
||||
alert('No se pudo cargar el formulario: ' + err.message);
|
||||
cerrarModalFirma();
|
||||
}
|
||||
}
|
||||
|
||||
function cerrarModalFirma() {
|
||||
|
||||
Reference in New Issue
Block a user