feat: mostrar nombre y cédula del profesional bajo la firma

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-29 21:10:33 -05:00
co-authored by Claude Sonnet 4.6
parent 806ae0b552
commit c85181ad56
2 changed files with 55 additions and 9 deletions
@@ -17,8 +17,11 @@ $turnoId = (int)($body['turno_id'] ?? 0);
$formularioId = (int)($body['formulario_id'] ?? 0);
$svg = $body['svg'] ?? '';
$soloPro = !empty($body['solo_profesional']);
$datosResp = (isset($body['datos_respuestas']) && is_array($body['datos_respuestas']))
? json_encode($body['datos_respuestas'], JSON_UNESCAPED_UNICODE) : null;
// Siempre mergeamos datos_respuestas (incluye _pro_nombre/_pro_cedula)
$datosResp = null;
if (isset($body['datos_respuestas']) && is_array($body['datos_respuestas']) && !empty($body['datos_respuestas'])) {
$datosResp = json_encode($body['datos_respuestas'], JSON_UNESCAPED_UNICODE);
}
if (!$turnoId) jsonError('turno_id requerido.');
if (!$formularioId) jsonError('formulario_id requerido.');
@@ -52,9 +55,12 @@ if ($soloPro) {
} else {
$pdo->prepare(
"UPDATE turnero_consentimientos
SET firma_profesional_svg = ?, firmado_profesional_at = NOW()
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, $turnoId, $formularioId]);
)->execute([$svg, $datosResp, $datosResp, $turnoId, $formularioId]);
}
notificarSSE((int)$tc['sesion_id']);
+45 -5
View File
@@ -250,13 +250,23 @@ $autoprint = isset($_GET['autoprint']) && $_GET['autoprint'] === '1';
// Firma pre-guardada del profesional logueado (para botón de 1 clic)
$firmaProfPreguardada = null;
$profNombre = null;
$profDocumento = null;
if ($modoTurnero && $embebido && isUserLoggedIn()) {
$uid = (int)($_SESSION['admin_user']['id'] ?? 0);
if ($uid) {
try {
$stmt = $db->getConnection()->prepare("SELECT firma_svg FROM admin_users WHERE id = ? LIMIT 1");
$stmt = $db->getConnection()->prepare(
"SELECT au.firma_svg, 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"
);
$stmt->execute([$uid]);
$firmaProfPreguardada = $stmt->fetchColumn() ?: null;
$pRow = $stmt->fetch(PDO::FETCH_ASSOC) ?: [];
$firmaProfPreguardada = $pRow['firma_svg'] ?: null;
$profNombre = $pRow['pro_nombre'] ?: null;
$profDocumento = $pRow['pro_documento'] ?: null;
} catch (\Throwable $_) {}
}
}
@@ -1084,6 +1094,15 @@ function _addExamWizardHtml(string $cid): string {
<div class="firma-box" style="border-color:<?= $fColor ?>">
<img src="<?= htmlspecialchars($fSvg) ?>" alt="<?= $fLabel ?>">
</div>
<?php if ($isPro):
$_pn = $datosCliente['_pro_nombre'] ?? $profNombre ?? null;
$_pd = $datosCliente['_pro_cedula'] ?? $profDocumento ?? null;
if ($_pn || $_pd): ?>
<div class="firma-pro-ident" style="font-size:13px;line-height:1.5;margin-top:4px">
<?php if ($_pn): ?><strong><?= esc2($_pn) ?></strong><br><?php endif; ?>
<?php if ($_pd): ?><span style="color:#6c757d;font-size:12px">C.C. <?= esc2($_pd) ?></span><?php endif; ?>
</div>
<?php endif; endif; ?>
<?php elseif ($fFoto): ?>
<div class="firma-box mt-2" style="border-color:<?= $fColor ?>">
<img src="<?= htmlspecialchars($fFoto) ?>" alt="Foto - <?= $fLabel ?>">
@@ -1152,6 +1171,12 @@ function _addExamWizardHtml(string $cid): string {
</div>
<?php if ($firmaProfPreguardada): ?></div><?php endif; ?>
<div class="fpw-msg mt-2 small"></div>
<?php if ($profNombre || $profDocumento): ?>
<div class="firma-pro-ident mt-2" style="font-size:13px;line-height:1.5">
<?php if ($profNombre): ?><strong><?= esc2($profNombre) ?></strong><br><?php endif; ?>
<?php if ($profDocumento): ?><span style="color:#6c757d;font-size:12px">C.C. <?= esc2($profDocumento) ?></span><?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php elseif ($modoPublico): ?>
<div class="alert py-2 px-3 no-print" style="background:#fff8e1;border:1.5px dashed #f59e0b;border-radius:8px;color:#92400e;font-size:.85rem">
@@ -2165,7 +2190,9 @@ document.addEventListener('DOMContentLoaded', function() {
}, 350);
});
<?php endif; ?>
window._fpwPreFirma = <?= json_encode($firmaProfPreguardada) ?>;
window._fpwPreFirma = <?= json_encode($firmaProfPreguardada) ?>;
window._profNombre = <?= json_encode($profNombre) ?>;
window._profDocumento = <?= json_encode($profDocumento) ?>;
<?php if (!empty($_mpSiguienteTomAt)): ?>
// Fix 1: recuperar countdown si el modal fue cerrado y reabierto mientras una toma estaba en curso
(function() {
@@ -2202,9 +2229,12 @@ function _guardarFirmaPro(widget, svg, msgEl) {
});
}
if (window._profNombre) datosRespuestas['_pro_nombre'] = window._profNombre;
if (window._profDocumento) datosRespuestas['_pro_cedula'] = window._profDocumento;
const payload = isTurnero
? { turno_id: parseInt(turnoId), formulario_id: parseInt(formularioId), svg,
...(soloPro ? { solo_profesional: true, datos_respuestas: datosRespuestas } : {}) }
datos_respuestas: datosRespuestas,
...(soloPro ? { solo_profesional: true } : {}) }
: { envio_id: envioId, campo_id: campoId, svg };
fetch(saveUrl, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload) })
@@ -2226,7 +2256,17 @@ function _guardarFirmaPro(widget, svg, msgEl) {
var box = document.createElement('div');
box.className = 'firma-box'; box.style.borderColor = '#198754';
box.appendChild(img);
widget.replaceWith(box);
var wrap = document.createElement('div');
wrap.appendChild(box);
if (window._profNombre || window._profDocumento) {
var ident = document.createElement('div');
ident.className = 'firma-pro-ident';
ident.style.cssText = 'font-size:13px;line-height:1.5;margin-top:4px';
if (window._profNombre) { var s = document.createElement('strong'); s.textContent = window._profNombre; ident.appendChild(s); ident.appendChild(document.createElement('br')); }
if (window._profDocumento) { var sp = document.createElement('span'); sp.style.cssText = 'color:#6c757d;font-size:12px'; sp.textContent = 'C.C. ' + window._profDocumento; ident.appendChild(sp); }
wrap.appendChild(ident);
}
widget.replaceWith(wrap);
}
} else {
if (msgEl) msgEl.innerHTML = '<span class="text-danger"><i class="fas fa-times me-1"></i>' + (data.error||'Error al guardar') + '</span>';