up
This commit is contained in:
@@ -55,6 +55,7 @@ class Formulario {
|
||||
'esquema' => $datos['esquema'] ?? '[]',
|
||||
'permite_firma' => !empty($datos['permite_firma']) ? 1 : 0,
|
||||
'requiere_firma' => !empty($datos['requiere_firma']) ? 1 : 0,
|
||||
'firma_modos' => $datos['firma_modos'] ?? 'canvas,foto',
|
||||
'doc_encabezado' => $datos['doc_encabezado'] ?? null,
|
||||
'doc_subtitulo' => $datos['doc_subtitulo'] ?? null,
|
||||
'doc_logo_base64' => $datos['doc_logo_base64'] ?? null,
|
||||
@@ -69,7 +70,7 @@ class Formulario {
|
||||
public function actualizar(int $id, array $datos, int $adminId): bool {
|
||||
$permitidos = [
|
||||
'nombre','descripcion','categoria','esquema',
|
||||
'permite_firma','requiere_firma','is_active',
|
||||
'permite_firma','requiere_firma','firma_modos','is_active',
|
||||
'doc_encabezado','doc_subtitulo','doc_logo_base64','doc_color','doc_pie_pagina',
|
||||
];
|
||||
$campos = array_intersect_key($datos, array_flip($permitidos));
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* fix_form_modos.php — Migración + corrección de modos de firma
|
||||
* 1. Aplica la columna firma_modos si no existe
|
||||
* 2. Muestra y permite corregir los modos por formulario
|
||||
* ELIMINAR después de usar.
|
||||
*/
|
||||
require_once 'config/config.php';
|
||||
if (!isUserLoggedIn()) { die('No autorizado'); }
|
||||
|
||||
$db = Database::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
// ── 1. Migración automática ──────────────────────────────────────────────────
|
||||
$migMsg = '';
|
||||
try {
|
||||
$pdo->exec("ALTER TABLE lab_formularios
|
||||
ADD COLUMN IF NOT EXISTS firma_modos VARCHAR(50) NOT NULL DEFAULT 'canvas,foto'
|
||||
COMMENT 'Modos habilitados: canvas, foto o ambos (CSV)'
|
||||
AFTER requiere_firma");
|
||||
$migMsg = '✅ Columna <code>firma_modos</code> lista.';
|
||||
} catch (PDOException $e) {
|
||||
$migMsg = '⚠️ ' . htmlspecialchars($e->getMessage());
|
||||
}
|
||||
|
||||
// ── 2. Guardar corrección manual ─────────────────────────────────────────────
|
||||
$saveMsg = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['form_id'])) {
|
||||
$fid = (int)$_POST['form_id'];
|
||||
$canvas = !empty($_POST['canvas']);
|
||||
$foto = !empty($_POST['foto']);
|
||||
$modos = [];
|
||||
if ($canvas) $modos[] = 'canvas';
|
||||
if ($foto) $modos[] = 'foto';
|
||||
if (!$modos) $modos = ['canvas']; // al menos canvas
|
||||
|
||||
$modosStr = implode(',', $modos);
|
||||
|
||||
// Actualiza columna firma_modos
|
||||
$upd = $pdo->prepare('UPDATE lab_formularios SET firma_modos = ? WHERE id = ?');
|
||||
$upd->execute([$modosStr, $fid]);
|
||||
|
||||
// También actualiza el campo tipo:'firma' dentro del esquema si existe
|
||||
$row = $pdo->prepare('SELECT esquema FROM lab_formularios WHERE id = ?');
|
||||
$row->execute([$fid]);
|
||||
$f = $row->fetch(PDO::FETCH_ASSOC);
|
||||
if ($f) {
|
||||
$esquema = json_decode($f['esquema'], true) ?? [];
|
||||
$changed = false;
|
||||
$esquema = array_map(function($c) use ($modos, &$changed) {
|
||||
if ($c['tipo'] === 'firma') { $c['modos'] = $modos; $changed = true; }
|
||||
return $c;
|
||||
}, $esquema);
|
||||
if ($changed) {
|
||||
$upd2 = $pdo->prepare('UPDATE lab_formularios SET esquema = ? WHERE id = ?');
|
||||
$upd2->execute([json_encode($esquema, JSON_UNESCAPED_UNICODE), $fid]);
|
||||
}
|
||||
}
|
||||
|
||||
$saveMsg = "✅ Formulario #$fid actualizado → modos: <strong>" . htmlspecialchars($modosStr) . '</strong>';
|
||||
}
|
||||
|
||||
// ── 3. Leer formularios ──────────────────────────────────────────────────────
|
||||
$stmt = $pdo->query('SELECT id, nombre, esquema, firma_modos FROM lab_formularios WHERE is_active = 1 ORDER BY id');
|
||||
$formularios = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Fix Modos Firma</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body class="p-4">
|
||||
<h4 class="mb-3">🔧 Migración y corrección de modos de firma</h4>
|
||||
<div class="alert alert-info"><?= $migMsg ?></div>
|
||||
<?php if ($saveMsg): ?><div class="alert alert-success"><?= $saveMsg ?></div><?php endif; ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-sm">
|
||||
<thead class="table-dark">
|
||||
<tr><th>#</th><th>Nombre</th><th>firma_modos (DB col)</th><th>modos en esquema JSON</th><th>Corregir</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($formularios as $f): ?>
|
||||
<?php
|
||||
$esquema = json_decode($f['esquema'], true) ?? [];
|
||||
$firmaCampo = null;
|
||||
foreach ($esquema as $c) { if ($c['tipo'] === 'firma') { $firmaCampo = $c; break; } }
|
||||
$modsCol = $f['firma_modos'] ?? 'canvas,foto';
|
||||
$modsArr = array_filter(explode(',', $modsCol));
|
||||
$modsJson = $firmaCampo['modos'] ?? null;
|
||||
$hayFotoCol = in_array('foto', $modsArr);
|
||||
$hayCanvasCol = in_array('canvas', $modsArr);
|
||||
?>
|
||||
<tr>
|
||||
<td><?= $f['id'] ?></td>
|
||||
<td><?= htmlspecialchars($f['nombre']) ?></td>
|
||||
<td>
|
||||
<code><?= htmlspecialchars($modsCol) ?></code>
|
||||
<?php if ($hayFotoCol): ?>
|
||||
<span class="badge bg-warning text-dark ms-1">📷 foto ACTIVA</span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-success ms-1">✅ foto off</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($modsJson !== null): ?>
|
||||
<code><?= htmlspecialchars(implode(', ', $modsJson)) ?></code>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">sin campo firma en esquema</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<form method="POST" class="d-flex gap-2 align-items-center">
|
||||
<input type="hidden" name="form_id" value="<?= $f['id'] ?>">
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="canvas" id="c<?= $f['id'] ?>" <?= $hayCanvasCol ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="c<?= $f['id'] ?>">✍️ Dibujar</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="foto" id="f<?= $f['id'] ?>" <?= $hayFotoCol ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="f<?= $f['id'] ?>">📷 Foto</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-sm btn-primary">Guardar</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="alert alert-warning mt-3">⚠️ Elimina este archivo del servidor después de usarlo.</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -937,8 +937,12 @@ async function cargarFormulario(id) {
|
||||
$('tb-firma').checked = !!f.permite_firma;
|
||||
$('tb-firma-req').checked = !!f.requiere_firma;
|
||||
_campos = f.esquema_decoded || [];
|
||||
// Leer modos: primero columna dedicada, luego campo tipo:'firma' en esquema, nunca defaultear a foto
|
||||
const _firmaCampo = _campos.find(c => c.tipo === 'firma');
|
||||
const _fModos = _firmaCampo?.modos || ['canvas','foto'];
|
||||
const _fModosStr = f.firma_modos || ''; // columna DB: 'canvas', 'foto', 'canvas,foto' o ''
|
||||
const _fModos = _fModosStr
|
||||
? _fModosStr.split(',').map(m => m.trim()).filter(Boolean)
|
||||
: (_firmaCampo?.modos ?? ['canvas','foto']);
|
||||
$('tb-firma-canvas').checked = _fModos.includes('canvas');
|
||||
$('tb-firma-foto').checked = _fModos.includes('foto');
|
||||
|
||||
@@ -984,7 +988,7 @@ async function guardar() {
|
||||
const usarGlobal = $('tb-usar-global').checked;
|
||||
// Sincronizar modos ANTES de serializar el esquema
|
||||
const _modos = []; if($('tb-firma-canvas').checked)_modos.push('canvas'); if($('tb-firma-foto').checked)_modos.push('foto');
|
||||
_campos = _campos.map(c => c.tipo === 'firma' ? { ...c, modos: _modos.length ? _modos : ['canvas','foto'] } : c);
|
||||
_campos = _campos.map(c => c.tipo === 'firma' ? { ...c, modos: _modos.length ? _modos : ['canvas'] } : c);
|
||||
const datos = {
|
||||
nombre,
|
||||
descripcion: $('tb-descripcion').value.trim() || null,
|
||||
@@ -992,6 +996,7 @@ async function guardar() {
|
||||
esquema: JSON.stringify(_campos),
|
||||
permite_firma: $('tb-firma').checked ? 1 : 0,
|
||||
requiere_firma: $('tb-firma-req').checked ? 1 : 0,
|
||||
firma_modos: _modos.length ? _modos.join(',') : 'canvas',
|
||||
doc_encabezado: usarGlobal ? null : ($('tb-doc-encabezado').value.trim() || null),
|
||||
doc_subtitulo: usarGlobal ? null : ($('tb-doc-subtitulo').value.trim() || null),
|
||||
doc_color: usarGlobal ? null : ($('tb-doc-color').value || null),
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
-- Agrega columna firma_modos a lab_formularios
|
||||
-- Almacena qué modos de captura están activos: 'canvas', 'foto', o ambos separados por coma.
|
||||
-- Valor por defecto: 'canvas,foto' (compatibilidad con registros anteriores)
|
||||
|
||||
ALTER TABLE lab_formularios
|
||||
ADD COLUMN IF NOT EXISTS firma_modos VARCHAR(50) NOT NULL DEFAULT 'canvas,foto'
|
||||
COMMENT 'Modos de firma habilitados: canvas, foto o ambos (CSV)'
|
||||
AFTER requiere_firma;
|
||||
Reference in New Issue
Block a user