diff --git a/migrations/20260616_turnero_consentimientos_datos.sql b/migrations/20260616_turnero_consentimientos_datos.sql new file mode 100644 index 0000000..8ecaaec --- /dev/null +++ b/migrations/20260616_turnero_consentimientos_datos.sql @@ -0,0 +1,4 @@ +-- Agrega columna para guardar respuestas de campos al firmar presencialmente +ALTER TABLE turnero_consentimientos + ADD COLUMN IF NOT EXISTS datos_respuestas MEDIUMTEXT DEFAULT NULL + COMMENT 'Respuestas del formulario en JSON (campos llenados al firmar presencialmente)'; diff --git a/run_migration_consentimientos_datos.php b/run_migration_consentimientos_datos.php new file mode 100644 index 0000000..7abe2cd --- /dev/null +++ b/run_migration_consentimientos_datos.php @@ -0,0 +1,52 @@ +getConnection(); + $sql = file_get_contents($sqlFile); + + $statements = array_filter(array_map('trim', explode(';', $sql))); + + echo "
π Ejecutando migraciΓ³n: 20260616_turnero_consentimientos_datos\n\n";
+
+ foreach ($statements as $stmt) {
+ $clean = preg_replace('/--[^\n]*/', '', $stmt);
+ $clean = trim($clean);
+ if (empty($clean)) continue;
+
+ try {
+ $pdo->exec($clean);
+ $preview = substr(preg_replace('/\s+/', ' ', $clean), 0, 120);
+ echo "β {$preview}\n";
+ } catch (PDOException $e) {
+ $msg = $e->getMessage();
+ if (str_contains($msg, 'Duplicate column') || str_contains($msg, 'errno: 1060')) {
+ echo "βΉοΈ (columna ya existe, omitida)\n";
+ } else {
+ throw $e;
+ }
+ }
+ }
+
+ echo "\nβ
MigraciΓ³n completada.\n";
+ echo " Columna agregada a turnero_consentimientos:\n";
+ echo " β’ datos_respuestas (MEDIUMTEXT, JSON con campos llenados al firmar presencialmente)\n";
+
+ $cols = $pdo->query("SHOW COLUMNS FROM turnero_consentimientos")->fetchAll(PDO::FETCH_COLUMN);
+ echo "π Columnas actuales: " . implode(', ', $cols) . "";
+
+} catch (Throwable $e) {
+ echo "β Error: " . htmlspecialchars($e->getMessage()) . "\n"; +} diff --git a/ver_formulario_enviado.php b/ver_formulario_enviado.php index 14adb76..8477f02 100644 --- a/ver_formulario_enviado.php +++ b/ver_formulario_enviado.php @@ -30,7 +30,7 @@ if ($modoTurnero) { $tcRow = $db->fetch( "SELECT tc.id, tc.turno_id, tc.formulario_id, tc.token, tc.estado, tc.enviado_at, tc.firmado_at, tc.ip_firma, tc.ua_firma, tc.firma_svg, - tc.firma_profesional_svg, tc.firmado_profesional_at, + tc.firma_profesional_svg, tc.firmado_profesional_at, tc.datos_respuestas, f.nombre AS form_nombre, f.categoria, f.descripcion AS form_descripcion, f.esquema, f.doc_encabezado, f.doc_subtitulo, f.doc_logo_base64, f.doc_color, f.doc_pie_pagina, p.nombre_completo AS paciente_nombre, @@ -58,6 +58,9 @@ if ($modoTurnero) { if (strlen($firmaSvg) < 100) { echo json_encode(['ok' => false, 'error' => 'Firma requerida']); exit; } + $datosRespuestas = isset($input['datos_respuestas']) && is_array($input['datos_respuestas']) + ? json_encode($input['datos_respuestas'], JSON_UNESCAPED_UNICODE) + : null; $ip = filter_var( $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '', FILTER_VALIDATE_IP @@ -67,10 +70,10 @@ if ($modoTurnero) { $stmt = $pdo->prepare( "UPDATE turnero_consentimientos SET estado='firmado', firmado_at=NOW(), firma_svg=?, - ip_firma=?, ua_firma=?, version_formulario=? + ip_firma=?, ua_firma=?, version_formulario=?, datos_respuestas=? WHERE token=?" ); - $stmt->execute([$firmaSvg, $ip, $ua, (int)$tcRow['formulario_id'], $tokenTurnero]); + $stmt->execute([$firmaSvg, $ip, $ua, (int)$tcRow['formulario_id'], $datosRespuestas, $tokenTurnero]); require_once __DIR__ . '/modules/turnero/api/_helpers.php'; notificarSSE((int)$tcRow['sesion_id']); echo json_encode(['ok' => true, 'message' => 'Consentimiento firmado correctamente']); exit; @@ -99,7 +102,7 @@ if ($modoTurnero) { 'enviado_por_nombre'=> $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['username'] ?? 'Turnero', 'enviado_por_email' => $_SESSION['admin_user']['email'] ?? null, 'firma_profesional_svg' => $tcRow['firma_profesional_svg'] ?? null, - 'datos_cliente' => '{}', + 'datos_cliente' => $tcRow['datos_respuestas'] ?: '{}', 'datos_prefilled' => json_encode(['__paciente' => [ 'nombre_completo' => $tcRow['paciente_nombre'] ?? '', 'numero_documento' => $tcRow['numero_documento'] ?? '', @@ -184,6 +187,7 @@ $esquema = json_decode($envio['esquema'], true) ?? []; $datosCliente = json_decode($envio['datos_cliente'] ?? '{}', true) ?? []; $datosPrefilled = json_decode($envio['datos_prefilled'] ?? '{}', true) ?? []; $todos = array_merge($datosPrefilled, $datosCliente); +$modoEditar = $modoTurnero && $envio['estado'] !== 'firmado'; // Mapa id β label $labelMap = []; @@ -299,6 +303,23 @@ function esc2(mixed $v): string { .fpw-canvas { border: 2px solid #198754; border-radius: 8px; background: #f8fff9; cursor: crosshair; display: block; max-width: 100%; touch-action: none; } + /* ββ Campos interactivos (modo turnero editar) ββββ */ + .campo-edit { margin-bottom: 14px; } + .campo-edit label { display: block; font-size: 12px; color: #6c757d; + font-weight: 600; margin-bottom: 4px; } + .campo-edit .form-control, + .campo-edit .form-select { font-size: 13px; border-color: #c3d3f7; + background: #f8faff; } + .campo-edit .form-control:focus, + .campo-edit .form-select:focus { border-color: #1565c0; + box-shadow: 0 0 0 3px rgba(21,101,192,.12); } + .campo-edit .form-check-label { font-size: 13px; } + .campo-linked { display: flex; gap: 16px; padding: 6px 0; + border-bottom: 1px solid #f0f0f0; } + .campo-linked-label { flex: 0 0 38%; font-size: 12px; color: #6c757d; } + .campo-linked-valor { flex: 1; font-size: 13px; font-weight: 600; + color: #1565c0; } + /* βββββββ ESTILOS DE IMPRESIΓN βββββββββββββββββββ */ @media print { body { background: #fff !important; font-size: 12px; } @@ -419,7 +440,10 @@ function esc2(mixed $v): string { -