From b2bc0f950a94f92fac4c29f60dec6e72ab313943 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:10:57 -0500 Subject: [PATCH] =?UTF-8?q?feat(turnero):=20m=C3=BAltiples=20consentimient?= =?UTF-8?q?os=20por=20tipo=20de=20examen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - save_ex_tipo.php: GET devuelve form_ids[], POST acepta form_ids[] y hace DELETE+INSERT por cada uno (la tabla ya soportaba muchos a muchos) - configuracion.php: reemplaza select único por checkboxes en formulario Agregar y modal Editar; JS lee los checks y envía form_ids[] Co-Authored-By: Claude Sonnet 4.6 --- modules/turnero/api/save_ex_tipo.php | 39 +++++++------- modules/turnero/views/configuracion.php | 68 ++++++++++++++++--------- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/modules/turnero/api/save_ex_tipo.php b/modules/turnero/api/save_ex_tipo.php index 7bee7b3..620d3a7 100644 --- a/modules/turnero/api/save_ex_tipo.php +++ b/modules/turnero/api/save_ex_tipo.php @@ -1,10 +1,10 @@ prepare( - 'SELECT et.*, - (SELECT formulario_id FROM exam_tipo_consentimientos - WHERE exam_tipo_id = et.id LIMIT 1) AS formulario_id - FROM exam_tipos et - WHERE et.id = ?' - ); + $stmt = db()->prepare('SELECT * FROM exam_tipos WHERE id = ?'); $stmt->execute([$id]); $data = $stmt->fetch(PDO::FETCH_ASSOC); if (!$data) jsonError('Examen no encontrado', 404); + + $fStmt = db()->prepare('SELECT formulario_id FROM exam_tipo_consentimientos WHERE exam_tipo_id = ?'); + $fStmt->execute([$id]); + $data['form_ids'] = $fStmt->fetchAll(PDO::FETCH_COLUMN); jsonOk(['data' => $data]); } @@ -52,11 +50,11 @@ if ($delete) { } // ── CREAR / ACTUALIZAR ─────────────────────────────────────── -$codigo = strtoupper(trim($input['codigo'] ?? '')); -$nombre = trim($input['nombre'] ?? ''); -$categoria = trim($input['categoria'] ?? ''); -$formId = (int)($input['formulario_id'] ?? 0) ?: null; -$activo = (int)($input['activo'] ?? 1); +$codigo = strtoupper(trim($input['codigo'] ?? '')); +$nombre = trim($input['nombre'] ?? ''); +$categoria = trim($input['categoria'] ?? ''); +$formIds = array_values(array_unique(array_filter(array_map('intval', (array)($input['form_ids'] ?? []))))); +$activo = (int)($input['activo'] ?? 1); if ($codigo === '') jsonError('El código es requerido'); if ($nombre === '') jsonError('El nombre es requerido'); @@ -80,12 +78,11 @@ try { $examId = (int)$pdo->lastInsertId(); } - // Actualizar relación formulario ↔ examen + // Actualizar relaciones formulario ↔ examen (muchos a muchos) $pdo->prepare('DELETE FROM exam_tipo_consentimientos WHERE exam_tipo_id = ?')->execute([$examId]); - if ($formId) { - $pdo->prepare( - 'INSERT INTO exam_tipo_consentimientos (exam_tipo_id, formulario_id) VALUES (?, ?)' - )->execute([$examId, $formId]); + $ins = $pdo->prepare('INSERT INTO exam_tipo_consentimientos (exam_tipo_id, formulario_id) VALUES (?, ?)'); + foreach ($formIds as $fid) { + $ins->execute([$examId, $fid]); } $pdo->commit(); diff --git a/modules/turnero/views/configuracion.php b/modules/turnero/views/configuracion.php index 627c5a3..3376005 100644 --- a/modules/turnero/views/configuracion.php +++ b/modules/turnero/views/configuracion.php @@ -675,13 +675,21 @@ $tab = $_GET['tab'] ?? 'lugares';
- - + +
- + + Sin formularios activos + +
- - + +
- + + Sin formularios activos + +
@@ -1340,15 +1356,17 @@ async function eliminarDispositivo(id, nombre) { // TAB 2: EXÁMENES // ───────────────────────────────────────────────────────────── async function guardarExamen(id = null) { - const codigo = (id ? document.getElementById('edit-ex-codigo') : document.getElementById('ex-codigo'))?.value.trim().toUpperCase(); - const nombre = (id ? document.getElementById('edit-ex-nombre') : document.getElementById('ex-nombre'))?.value.trim(); - const categoria = (id ? document.getElementById('edit-ex-categoria'): document.getElementById('ex-categoria'))?.value.trim(); - const formId = parseInt((id ? document.getElementById('edit-ex-form') : document.getElementById('ex-form'))?.value) || null; + const prefix = id ? 'edit-ex' : 'ex'; + const codigo = document.getElementById(prefix + '-codigo')?.value.trim().toUpperCase(); + const nombre = document.getElementById(prefix + '-nombre')?.value.trim(); + const categoria = document.getElementById(prefix + '-categoria')?.value.trim(); const activo = id ? (document.getElementById('edit-ex-activo')?.checked ? 1 : 0) : 1; + const chkClass = id ? 'edit-ex-form-chk' : 'ex-form-chk'; + const form_ids = [...document.querySelectorAll(`.${chkClass}:checked`)].map(c => parseInt(c.value)); if (!codigo || !nombre) { toast('Código y nombre son requeridos', 'error'); return; } - const body = { codigo, nombre, categoria, formulario_id: formId, activo }; + const body = { codigo, nombre, categoria, form_ids, activo }; if (id) body.id = id; try { @@ -1359,25 +1377,27 @@ async function guardarExamen(id = null) { if (!json.ok) { toast(json.error || 'Error', 'error'); return; } toast(id ? 'Examen actualizado' : 'Examen creado'); if (id) bootstrap.Modal.getInstance(document.getElementById('modalEditarExamen'))?.hide(); + // Limpiar checkboxes del formulario de agregar + if (!id) document.querySelectorAll('.ex-form-chk').forEach(c => c.checked = false); setTimeout(() => location.reload(), 600); } catch (e) { toast('Error de conexión', 'error'); } } function editarExamen(id) { - const row = document.querySelector(`[data-exam-id="${id}"]`); - const tags = row ? row.querySelectorAll('.consent-tag') : []; - // Leer datos de los atributos del servidor (via fetch de datos ya cargados) fetch(API + 'save_ex_tipo.php?id=' + id) .then(r => r.json()) .then(json => { if (!json.ok) return; const d = json.data; - document.getElementById('edit-ex-id').value = d.id; - document.getElementById('edit-ex-codigo').value = d.codigo; - document.getElementById('edit-ex-nombre').value = d.nombre; - document.getElementById('edit-ex-categoria').value= d.categoria || ''; - document.getElementById('edit-ex-form').value = d.formulario_id || ''; - document.getElementById('edit-ex-activo').checked = !!d.activo; + document.getElementById('edit-ex-id').value = d.id; + document.getElementById('edit-ex-codigo').value = d.codigo; + document.getElementById('edit-ex-nombre').value = d.nombre; + document.getElementById('edit-ex-categoria').value = d.categoria || ''; + document.getElementById('edit-ex-activo').checked = !!d.activo; + // Marcar consentimientos vinculados + document.querySelectorAll('.edit-ex-form-chk').forEach(chk => { + chk.checked = (d.form_ids || []).includes(parseInt(chk.value)); + }); new bootstrap.Modal(document.getElementById('modalEditarExamen')).show(); }) .catch(() => toast('Error cargando datos', 'error'));