From 0b8418ec761247c786d8d3de19dbf35b9dcce5ea Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Mon, 3 Aug 2026 11:44:31 -0500 Subject: [PATCH] Historial turnero: desglose de tomas de muestra y modal para documentos firmados MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Muestra el detalle de cada toma (tipo, quien la recibió, tiempo) cuando un turno tuvo varias, para explicar tiempos de servicio prolongados. Los documentos firmados ahora se abren en un modal en vez de nueva pestaña, preservando los filtros de búsqueda activos. Co-Authored-By: Claude Sonnet 4.6 --- modules/turnero/api/get_historial.php | 24 ++++++++++- modules/turnero/views/historial.php | 59 +++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/modules/turnero/api/get_historial.php b/modules/turnero/api/get_historial.php index 6290d75..d86025d 100644 --- a/modules/turnero/api/get_historial.php +++ b/modules/turnero/api/get_historial.php @@ -139,11 +139,12 @@ $stmtTurnos = $pdo->prepare($sqlTurnos); $stmtTurnos->execute($bindsPage); $turnos = $stmtTurnos->fetchAll(PDO::FETCH_ASSOC); -// ── Enriquecer con exámenes, consentimientos y comentarios (batch) ─ +// ── Enriquecer con exámenes, consentimientos, comentarios y tomas (batch) ─ $turnoIds = array_column($turnos, 'id'); $examenes = []; $consentimientos = []; $comentarios = []; +$tomas = []; if ($turnoIds) { $ph = implode(',', array_fill(0, count($turnoIds), '?')); @@ -193,6 +194,26 @@ if ($turnoIds) { $comentarios[$tid][] = $row; } } + + // Tomas de muestra — batch (una solicitud por turno, varias tomas por solicitud) + $stmtTom = $pdo->prepare( + "SELECT ts.turno_id, tm.tipo_muestra, tm.estado, tm.creado_at, tm.recibida_at, + ar.full_name AS recibida_por_nombre + FROM turnero_muestras tm + JOIN turnero_solicitudes ts ON ts.id = tm.solicitud_id + LEFT JOIN admin_users ar ON ar.id = tm.recibida_por + WHERE ts.turno_id IN ($ph) + ORDER BY tm.creado_at ASC" + ); + $stmtTom->execute($turnoIds); + foreach ($stmtTom->fetchAll(PDO::FETCH_ASSOC) as $row) { + $tid = (int)$row['turno_id']; + unset($row['turno_id']); + $row['tiempo_min'] = ($row['creado_at'] && $row['recibida_at']) + ? round((strtotime($row['recibida_at']) - strtotime($row['creado_at'])) / 60, 1) + : null; + $tomas[$tid][] = $row; + } } foreach ($turnos as &$turno) { @@ -200,6 +221,7 @@ foreach ($turnos as &$turno) { $turno['examenes'] = $examenes[$tid] ?? []; $turno['consentimientos'] = $consentimientos[$tid] ?? []; $turno['comentarios'] = $comentarios[$tid] ?? []; + $turno['tomas'] = $tomas[$tid] ?? []; } // ── Resumen por estado (del rango filtrado) ─────────────────── diff --git a/modules/turnero/views/historial.php b/modules/turnero/views/historial.php index 42e3086..4116270 100644 --- a/modules/turnero/views/historial.php +++ b/modules/turnero/views/historial.php @@ -126,6 +126,18 @@ Layout::open('Historial de Turnos', 'fas fa-history'); .estado-modal select { width:100%; padding:8px 10px; border:1px solid #e2e8f0; border-radius:8px; font-size:.85rem; margin-bottom:16px; } .estado-modal .actions { display:flex; gap:8px; justify-content:flex-end; } + + /* ── Modal documento firmado ── */ + .doc-modal-backdrop { + position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:1060; + display:flex; align-items:center; justify-content:center; padding:20px; + } + .doc-modal { background:#fff; border-radius:12px; width:100%; max-width:820px; height:88vh; + display:flex; flex-direction:column; overflow:hidden; box-shadow:0 20px 60px rgba(0,0,0,.25); } + .doc-modal-head { display:flex; align-items:center; gap:10px; padding:12px 16px; border-bottom:1px solid #e2e8f0; } + .doc-modal-head h5 { font-size:.9rem; font-weight:700; margin:0; flex:1; } + .doc-modal-head button { border:none; background:none; font-size:1.1rem; color:#64748b; cursor:pointer; } + .doc-modal iframe { flex:1; border:none; width:100%; } @@ -521,6 +533,25 @@ function renderDetalle(t) { `; } + // Tomas de muestra (solo si hay más de una — turno prolongado por varias tomas) + let tomasHtml = ''; + if (t.tomas && t.tomas.length > 1) { + tomasHtml = `
+
Tomas de muestra (${t.tomas.length})
+ + + + ${t.tomas.map(m => ` + + + + + `).join('')} + +
MuestraRecibióRecibidaTiempo
${esc(m.tipo_muestra)}${esc(m.recibida_por_nombre || '—')}${m.recibida_at ? new Date(m.recibida_at.replace(' ','T')).toLocaleTimeString('es-CO',{hour:'2-digit',minute:'2-digit'}) : '—'}${m.tiempo_min != null ? m.tiempo_min + ' m' : '—'}
+
`; + } + // Comentarios let comHtml = ''; if (t.comentarios && t.comentarios.length) { @@ -543,7 +574,7 @@ function renderDetalle(t) {
${it.val}
`).join('')} - ${examHtml}${comHtml} + ${examHtml}${tomasHtml}${comHtml}
Documentos
Cargando… @@ -586,9 +617,8 @@ async function cargarDocumentosTurno(turnoId, container) { const nombre = esc(c.formulario_nombre || 'Documento'); if (est === 'firmado' && c.token) { const url = BASE_URL_ROOT + 'ver_formulario_enviado.php?token=' + encodeURIComponent(c.token); - return ` + return ` ${nombre} - `; } const cls = est === 'enviado' || est === 'visto' ? 'enviado' : 'pendiente'; @@ -746,6 +776,29 @@ async function confirmarCambioEstado() { } } +// ── Modal documento firmado ──────────────────────────────────── +function abrirDocModal(ev, url, nombre) { + ev.preventDefault(); + const backdrop = document.createElement('div'); + backdrop.className = 'doc-modal-backdrop'; + backdrop.id = 'docModalBackdrop'; + backdrop.innerHTML = ` +
+
+
${esc(nombre)}
+ + +
+ +
`; + backdrop.addEventListener('click', cerrarDocModal); + document.body.appendChild(backdrop); + return false; +} +function cerrarDocModal() { + document.getElementById('docModalBackdrop')?.remove(); +} + // ── Helpers visuales ────────────────────────────────────────── function mostrarSpinner() { document.getElementById('tbody').innerHTML =