diff --git a/migrations/20260616_turnero_comentarios.sql b/migrations/20260616_turnero_comentarios.sql new file mode 100644 index 0000000..293260c --- /dev/null +++ b/migrations/20260616_turnero_comentarios.sql @@ -0,0 +1,14 @@ +-- Tabla para comentarios de seguimiento en el turnero +CREATE TABLE IF NOT EXISTS turnero_comentarios ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + turno_id INT UNSIGNED NOT NULL, + usuario_id INT, + usuario_nombre VARCHAR(150) NOT NULL DEFAULT '', + comentario TEXT NOT NULL, + tipo ENUM('recepcion','muestras','general') NOT NULL DEFAULT 'general', + creado_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + actualizado_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (turno_id) REFERENCES turnero_turnos(id) ON DELETE CASCADE, + INDEX idx_turno (turno_id), + INDEX idx_creado (creado_at) +); diff --git a/modules/turnero/api/comentarios.php b/modules/turnero/api/comentarios.php new file mode 100644 index 0000000..9b5749e --- /dev/null +++ b/modules/turnero/api/comentarios.php @@ -0,0 +1,95 @@ +prepare( + "SELECT id, usuario_nombre, comentario, tipo, creado_at + FROM turnero_comentarios + WHERE turno_id = ? + ORDER BY creado_at DESC" + ); + $stmtCom->execute([$turnoId]); + $datos['comentarios'] = $stmtCom->fetchAll(PDO::FETCH_ASSOC); + + // Exámenes solicitados (si lo pide) + if (!empty($_GET['incluir_examenes'])) { + $stmtExam = $pdo->prepare( + "SELECT DISTINCT et.nombre, et.codigo + FROM turnero_examen_items tei + JOIN exam_tipos et ON et.id = tei.exam_tipo_id + WHERE tei.solicitud_id = ( + SELECT id FROM turnero_solicitudes + WHERE turno_id = ? LIMIT 1 + ) + ORDER BY et.nombre ASC" + ); + $stmtExam->execute([$turnoId]); + $datos['examenes'] = $stmtExam->fetchAll(PDO::FETCH_ASSOC); + } + + // Consentimientos (si lo pide) + if (!empty($_GET['incluir_consentimientos'])) { + $stmtCons = $pdo->prepare( + "SELECT tc.id, f.nombre, tc.estado, tc.firmado_at, tc.firma_profesional_svg + FROM turnero_consentimientos tc + LEFT JOIN lab_formularios f ON f.id = tc.formulario_id + WHERE tc.turno_id = ? + ORDER BY tc.estado DESC, tc.firmado_at DESC" + ); + $stmtCons->execute([$turnoId]); + $datos['consentimientos'] = $stmtCons->fetchAll(PDO::FETCH_ASSOC); + } + + jsonOk($datos); +} + +// ── POST: Guardar comentario ── +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $datos = inputJson(); + $turnoId = (int)($datos['turno_id'] ?? 0); + $comentario = trim($datos['comentario'] ?? ''); + $tipo = $datos['tipo'] ?? 'general'; + + if ($turnoId <= 0) jsonError('turno_id requerido.'); + if (!$comentario) jsonError('Comentario vacío.'); + if (!in_array($tipo, ['recepcion','muestras','general'], true)) $tipo = 'general'; + + // Validar que el turno existe + $stmtTurno = $pdo->prepare("SELECT id FROM turnero_turnos WHERE id = ?"); + $stmtTurno->execute([$turnoId]); + if (!$stmtTurno->fetch()) jsonError('Turno no encontrado.', 404); + + // Guardar comentario + $stmtIns = $pdo->prepare( + "INSERT INTO turnero_comentarios (turno_id, usuario_id, usuario_nombre, comentario, tipo) + VALUES (?, ?, ?, ?, ?)" + ); + $stmtIns->execute([$turnoId, $userId, $userName, $comentario, $tipo]); + $comId = (int)$pdo->lastInsertId(); + + jsonOk(['id' => $comId, 'creado_at' => date('c')]); +} diff --git a/modules/turnero/api/get_historial.php b/modules/turnero/api/get_historial.php index af913a7..ae43635 100644 --- a/modules/turnero/api/get_historial.php +++ b/modules/turnero/api/get_historial.php @@ -129,6 +129,44 @@ $stmtTurnos = $pdo->prepare($sqlTurnos); $stmtTurnos->execute($bindsPage); $turnos = $stmtTurnos->fetchAll(PDO::FETCH_ASSOC); +// ── Enriquecer con exámenes y consentimientos ────────────────── +foreach ($turnos as &$turno) { + // Exámenes + $stmtExam = $pdo->prepare( + "SELECT DISTINCT et.nombre, et.codigo + FROM turnero_examen_items tei + JOIN exam_tipos et ON et.id = tei.exam_tipo_id + WHERE tei.solicitud_id = ( + SELECT id FROM turnero_solicitudes WHERE turno_id = ? LIMIT 1 + ) + ORDER BY et.nombre ASC" + ); + $stmtExam->execute([(int)$turno['id']]); + $turno['examenes'] = $stmtExam->fetchAll(PDO::FETCH_ASSOC); + + // Consentimientos + $stmtCons = $pdo->prepare( + "SELECT tc.id, f.nombre, tc.estado, tc.firmado_at + FROM turnero_consentimientos tc + LEFT JOIN lab_formularios f ON f.id = tc.formulario_id + WHERE tc.turno_id = ? + ORDER BY tc.estado DESC, tc.firmado_at DESC" + ); + $stmtCons->execute([(int)$turno['id']]); + $turno['consentimientos'] = $stmtCons->fetchAll(PDO::FETCH_ASSOC); + + // Comentarios + $stmtCom = $pdo->prepare( + "SELECT usuario_nombre, comentario, tipo, creado_at + FROM turnero_comentarios + WHERE turno_id = ? + ORDER BY creado_at DESC + LIMIT 3" + ); + $stmtCom->execute([(int)$turno['id']]); + $turno['comentarios'] = $stmtCom->fetchAll(PDO::FETCH_ASSOC); +} + // ── Resumen por estado (del rango filtrado) ─────────────────── $sqlRes = " SELECT t.estado, COUNT(*) AS cnt diff --git a/modules/turnero/views/lugar.php b/modules/turnero/views/lugar.php index 6ffa473..2ab027a 100644 --- a/modules/turnero/views/lugar.php +++ b/modules/turnero/views/lugar.php @@ -314,6 +314,25 @@ require_once __DIR__ . '/../../../shared/components/sidebar.php'; + +
+
+
Comentarios del seguimiento
+
+
+ + +
+
+ Cargando comentarios… +
+
+