Tres correcciones sobre lo reportado en E042. 1. La bitácora daba por hecho que firmado_at era del paciente, y lo anunciaba así en documentos que el paciente nunca firma: el F-LAB-08 solo lo firma el profesional y el F-LAB-28 lleva una firma por toma. Ahora mira qué firma hay realmente guardada; si no hay ninguna dice «completado» o «protocolo cerrado», según el caso. 2. Los protocolos prolongados desglosan cada toma con su hora y su firmante, que es el dato que interesa: en E042 se ve que el minuto 0 lo firmó Yesica y el minuto 150 Omaira. La firma general no distinguía eso. 3. firmar_profesional_consentimiento.php aceptaba el nombre del firmante que mandaba el navegador, y ese valor se carga al abrir la página: si el personal cambiaba de turno sin recargar, la firma final quedaba a nombre de quien abrió el formulario. Ahora se resuelve desde la sesión en el servidor, igual que ya hacía guardar_toma.php para cada toma. Además, llamar y rellamar no dejaban rastro —el turno solo guarda la hora del último llamado, que el rellamado sobrescribe—, así que la bitácora mostraba «Llamado a X» sin autor. Ahora se auditan ambos. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
94 lines
3.7 KiB
PHP
94 lines
3.7 KiB
PHP
<?php
|
|
/**
|
|
* POST /modules/turnero/api/firmar_profesional_consentimiento.php
|
|
* Guarda la firma del enfermero/profesional en un consentimiento del turnero.
|
|
*
|
|
* Body JSON:
|
|
* turno_id int requerido
|
|
* formulario_id int requerido
|
|
* svg string requerido (data URI SVG o PNG base64)
|
|
*/
|
|
require_once __DIR__ . '/_helpers.php';
|
|
requireMethod('POST');
|
|
requireTurnero();
|
|
|
|
$body = inputJson();
|
|
$turnoId = (int)($body['turno_id'] ?? 0);
|
|
$formularioId = (int)($body['formulario_id'] ?? 0);
|
|
$svg = $body['svg'] ?? '';
|
|
$soloPro = !empty($body['solo_profesional']);
|
|
// Siempre mergeamos datos_respuestas (incluye _pro_nombre/_pro_cedula)
|
|
$datosResp = null;
|
|
$datosArr = (isset($body['datos_respuestas']) && is_array($body['datos_respuestas']))
|
|
? $body['datos_respuestas'] : [];
|
|
|
|
if (!$turnoId) jsonError('turno_id requerido.');
|
|
if (!$formularioId) jsonError('formulario_id requerido.');
|
|
if (strlen($svg) < 100) jsonError('Firma requerida.');
|
|
if (!preg_match('/^data:image\/(svg\+xml|png|jpeg|webp);base64,/i', $svg)) {
|
|
jsonError('Formato de firma no válido.');
|
|
}
|
|
|
|
$pdo = db();
|
|
|
|
// Quién firma se resuelve aquí y no se toma del navegador. El cliente manda el
|
|
// nombre que cargó al abrir la página, y si el personal cambia de turno sin
|
|
// recargar, la firma quedaba a nombre de quien abrió el formulario en vez de
|
|
// quien la está haciendo. La sesión del servidor es la única fuente confiable.
|
|
// (guardar_toma.php ya lo hacía así para cada toma; esto alinea la firma final.)
|
|
$__uid = adminId();
|
|
if ($__uid) {
|
|
$stmtPro = $pdo->prepare(
|
|
"SELECT au.full_name, au.cedula AS au_cedula,
|
|
le.nombre_completo AS pro_nombre, le.numero_documento AS pro_documento
|
|
FROM admin_users au
|
|
LEFT JOIN lab_enfermeras le ON le.id = au.enfermera_id
|
|
WHERE au.id = ? LIMIT 1"
|
|
);
|
|
$stmtPro->execute([$__uid]);
|
|
$pro = $stmtPro->fetch(PDO::FETCH_ASSOC) ?: [];
|
|
$proNombre = ($pro['pro_nombre'] ?? null) ?: ($pro['full_name'] ?? null);
|
|
$proCedula = ($pro['au_cedula'] ?? null) ?: ($pro['pro_documento'] ?? null);
|
|
if ($proNombre) $datosArr['_pro_nombre'] = $proNombre;
|
|
if ($proCedula) $datosArr['_pro_cedula'] = $proCedula;
|
|
$datosArr['_pro_id'] = $__uid;
|
|
}
|
|
if (!empty($datosArr)) {
|
|
$datosResp = json_encode($datosArr, JSON_UNESCAPED_UNICODE);
|
|
}
|
|
|
|
$stmt = $pdo->prepare(
|
|
"SELECT tc.id, tc.estado, t.sesion_id
|
|
FROM turnero_consentimientos tc
|
|
JOIN turnero_turnos t ON t.id = tc.turno_id
|
|
WHERE tc.turno_id = ? AND tc.formulario_id = ?"
|
|
);
|
|
$stmt->execute([$turnoId, $formularioId]);
|
|
$tc = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$tc) jsonError('Consentimiento no encontrado.', 404);
|
|
|
|
if ($soloPro) {
|
|
// El profesional es el firmante final: guardar datos + marcar como firmado
|
|
$pdo->prepare(
|
|
"UPDATE turnero_consentimientos
|
|
SET firma_profesional_svg = ?, firmado_profesional_at = NOW(),
|
|
estado = 'firmado', firmado_at = NOW(),
|
|
datos_respuestas = COALESCE(?, datos_respuestas)
|
|
WHERE turno_id = ? AND formulario_id = ?"
|
|
)->execute([$svg, $datosResp, $turnoId, $formularioId]);
|
|
} else {
|
|
$pdo->prepare(
|
|
"UPDATE turnero_consentimientos
|
|
SET firma_profesional_svg = ?, firmado_profesional_at = NOW(),
|
|
datos_respuestas = CASE WHEN ? IS NOT NULL
|
|
THEN JSON_MERGE_PATCH(COALESCE(datos_respuestas,'{}'), ?)
|
|
ELSE datos_respuestas END
|
|
WHERE turno_id = ? AND formulario_id = ?"
|
|
)->execute([$svg, $datosResp, $datosResp, $turnoId, $formularioId]);
|
|
}
|
|
|
|
notificarSSE((int)$tc['sesion_id']);
|
|
|
|
jsonOk(['mensaje' => 'Firma del profesional guardada correctamente.']);
|