Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
Asistencia_Capacitacion
/
Modelos
:
AsistenciaModel.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php // File: Modelos/AsistenciaModel.php require_once 'Database.php'; class AsistenciaModel { private $db; public function __construct() { $this->db = Database::getInstance()->getConnection(); $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $this->db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); } // --------------------------------------------------------------- // Obtener capacitaciones filtradas por empresa (case-insensitive) // --------------------------------------------------------------- public function getCapacitaciones($empresaNombreLogueado) { try { $sql = " SELECT c.CODIGO, c.CAPACITACION, c.empresa_id, e.nombre_empresa FROM capacitaciones c JOIN empresa e ON c.empresa_id = e.id WHERE LOWER(e.nombre_empresa) = LOWER(:nombre_empresa_filtro) ORDER BY c.CAPACITACION ASC "; $stmt = $this->db->prepare($sql); $stmt->bindParam(':nombre_empresa_filtro', $empresaNombreLogueado, PDO::PARAM_STR); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("AsistenciaModel ERROR en getCapacitaciones: " . $e->getMessage()); return []; } } // --------------------------------------------------------------- // Registro de ENTRADA // --------------------------------------------------------------- public function registrarEntrada($codigo, $capacitacion, $empresaNombreLogueado) { try { $fecha_actual = date("Y-m-d"); // Paso 1: Obtener datos del empleado $sql = "SELECT CONCAT(nombre, ' ', apellido) as nombre, ccosto, descripcion, cargo, empresa FROM empleados WHERE cedula = :codigo"; $stmt = $this->db->prepare($sql); $stmt->bindParam(':codigo', $codigo, PDO::PARAM_STR); $stmt->execute(); $empleado = $stmt->fetch(PDO::FETCH_ASSOC); if (!$empleado) { return ['success' => false, 'message' => "Cedula o codigo de barras no existe en la base de datos."]; } $empleadoEmpresa = trim($empleado['empresa']); // Paso 2: Obtener la empresa de la capacitación $sql = "SELECT e.nombre_empresa FROM capacitaciones c JOIN empresa e ON c.empresa_id = e.id WHERE c.CODIGO = :capacitacion_codigo"; $stmt = $this->db->prepare($sql); $stmt->bindParam(':capacitacion_codigo', $capacitacion, PDO::PARAM_STR); $stmt->execute(); $capacitacionEmpresa = $stmt->fetchColumn(); if (!$capacitacionEmpresa) { return ['success' => false, 'message' => "Capacitación no encontrada o no tiene empresa asignada."]; } $capacitacionEmpresa = trim($capacitacionEmpresa); // Validación 1: Empresa del empleado vs empresa de la capacitación if (strcasecmp($empleadoEmpresa, $capacitacionEmpresa) !== 0) { return ['success' => false, 'message' => "Error de Validación: El empleado de '{$empleadoEmpresa}' no puede registrar asistencia en la capacitación de '{$capacitacionEmpresa}'."]; } // Validación 2: Empresa de la capacitación vs empresa del usuario logueado if (strcasecmp($capacitacionEmpresa, trim($empresaNombreLogueado)) !== 0) { return ['success' => false, 'message' => "Error de Seguridad: La capacitación no pertenece a la empresa '{$empresaNombreLogueado}'. [cap:{$capacitacionEmpresa}]"]; } // Paso 3: Verificar duplicados $sql = "SELECT id FROM asistencia WHERE cedula = :codigo AND capacitacion = :capacitacion AND DATE(fecha) = :fecha_actual AND horaSalida IS NULL"; $stmt = $this->db->prepare($sql); $stmt->bindParam(':codigo', $codigo, PDO::PARAM_STR); $stmt->bindParam(':capacitacion', $capacitacion, PDO::PARAM_STR); $stmt->bindParam(':fecha_actual', $fecha_actual, PDO::PARAM_STR); $stmt->execute(); if ($stmt->rowCount() > 0) { return ['success' => false, 'message' => "Ya tiene una ENTRADA pendiente para esta capacitacion hoy."]; } // Paso 4: Insertar $sql = "INSERT INTO asistencia (capacitacion, cedula, nombre, ccosto, descripcion, cargo, empresa, fecha, hora, estado) VALUES (:capacitacion, :codigo, :nombre, :ccosto, :descripcion, :cargo, :empresa_nombre, CURDATE(), CURTIME(), 0)"; $stmt = $this->db->prepare($sql); $stmt->bindParam(':capacitacion', $capacitacion, PDO::PARAM_STR); $stmt->bindParam(':codigo', $codigo, PDO::PARAM_STR); $stmt->bindParam(':nombre', $empleado['nombre'], PDO::PARAM_STR); $stmt->bindParam(':ccosto', $empleado['ccosto'], PDO::PARAM_STR); $stmt->bindParam(':descripcion', $empleado['descripcion'],PDO::PARAM_STR); $stmt->bindParam(':cargo', $empleado['cargo'], PDO::PARAM_STR); $stmt->bindParam(':empresa_nombre', $empleado['empresa'], PDO::PARAM_STR); if ($stmt->execute()) { return [ 'success' => true, 'message' => "Registro de ENTRADA exitoso para " . $empleado['nombre'], 'nombre' => $empleado['nombre'], 'cedula' => $codigo ]; } else { $errorInfo = $stmt->errorInfo(); return ['success' => false, 'message' => "Error al registrar la asistencia: " . $errorInfo[2]]; } } catch (PDOException $e) { error_log("PDOException en registrarEntrada: " . $e->getMessage()); return ['success' => false, 'message' => "Error de Base de Datos: " . $e->getMessage()]; } } // --------------------------------------------------------------- // Registro de SALIDA // --------------------------------------------------------------- public function registrarSalida($codigo, $capacitacion, $empresaNombreLogueado) { try { $fecha_actual = date("Y-m-d"); // Paso 1: Obtener la empresa de la capacitación $sql = "SELECT e.nombre_empresa FROM capacitaciones c JOIN empresa e ON c.empresa_id = e.id WHERE c.CODIGO = :capacitacion_codigo"; $stmt = $this->db->prepare($sql); $stmt->bindParam(':capacitacion_codigo', $capacitacion, PDO::PARAM_STR); $stmt->execute(); $capacitacionEmpresa = $stmt->fetchColumn(); if (!$capacitacionEmpresa) { return ['success' => false, 'message' => "Capacitación no encontrada o no tiene empresa asignada."]; } $capacitacionEmpresa = trim($capacitacionEmpresa); // Validación de seguridad: capacitación debe pertenecer a la empresa logueada if (strcasecmp($capacitacionEmpresa, trim($empresaNombreLogueado)) !== 0) { return ['success' => false, 'message' => "Error de Seguridad: Esta capacitación pertenece a '{$capacitacionEmpresa}' y no a '{$empresaNombreLogueado}'."]; } // Paso 2: Buscar entrada pendiente $sql = "SELECT id, nombre, empresa FROM asistencia WHERE cedula = :codigo AND capacitacion = :capacitacion AND DATE(fecha) = :fecha_actual AND horaSalida IS NULL"; $stmt = $this->db->prepare($sql); $stmt->bindParam(':codigo', $codigo, PDO::PARAM_STR); $stmt->bindParam(':capacitacion', $capacitacion, PDO::PARAM_STR); $stmt->bindParam(':fecha_actual', $fecha_actual, PDO::PARAM_STR); $stmt->execute(); $registro = $stmt->fetch(PDO::FETCH_ASSOC); if (!$registro) { return ['success' => false, 'message' => "No se encontró un registro de ENTRADA pendiente para la cédula $codigo en la capacitación '$capacitacion'."]; } // Validación: empleado debe pertenecer a la misma empresa de la capacitación if (strcasecmp(trim($registro['empresa']), $capacitacionEmpresa) !== 0) { return ['success' => false, 'message' => "Error: El empleado de '{$registro['empresa']}' no pertenece a la empresa '{$capacitacionEmpresa}' de la capacitación."]; } // Paso 3: Registrar salida $sql = "UPDATE asistencia SET horaSalida = CURTIME(), estado = 1 WHERE id = :id"; $stmt = $this->db->prepare($sql); $stmt->bindParam(':id', $registro['id'], PDO::PARAM_INT); if ($stmt->execute()) { return [ 'success' => true, 'message' => "Salida registrada correctamente para " . $registro['nombre'], 'nombre' => $registro['nombre'], 'cedula' => $codigo ]; } else { $errorInfo = $stmt->errorInfo(); return ['success' => false, 'message' => "Error al registrar la salida: " . $errorInfo[2]]; } } catch (PDOException $e) { error_log("PDOException en registrarSalida: " . $e->getMessage()); return ['success' => false, 'message' => "Error de Base de Datos: " . $e->getMessage()]; } } // --------------------------------------------------------------- // Obtener registros de asistencia para consulta (CON FILTROS) // --------------------------------------------------------------- // $nombreEmpresa = nombre de la empresa del usuario logueado // $verTodos = boolean para quitar/poner el LIMIT 300 // $filtros = array con claves: cedula, capacitacion, fecha_desde, fecha_hasta // --------------------------------------------------------------- public function getRegistrosAsistencia($nombreEmpresa, $verTodos = false, $filtros = []) { try { // Construir la consulta base $sql = " SELECT id, capacitacion, cedula, nombre, ccosto, descripcion, cargo, empresa, fecha, hora, horaSalida, estado, CASE WHEN estado = 0 THEN 'Pendiente por salida' WHEN estado = 1 THEN 'Salida Registrada' ELSE 'Estado desconocido' END as estado_texto FROM asistencia WHERE LOWER(empresa) = LOWER(:nombre_empresa_filtro) "; // --- Agregar filtros dinámicos --- $params = [':nombre_empresa_filtro' => $nombreEmpresa]; // Filtro por Cédula if (!empty($filtros['cedula'])) { $sql .= " AND cedula LIKE :cedula"; $params[':cedula'] = '%' . $filtros['cedula'] . '%'; } // Filtro por Capacitación if (!empty($filtros['capacitacion'])) { $sql .= " AND capacitacion = :capacitacion"; $params[':capacitacion'] = $filtros['capacitacion']; } // Filtro por Fecha Desde if (!empty($filtros['fecha_desde'])) { $sql .= " AND DATE(fecha) >= :fecha_desde"; $params[':fecha_desde'] = $filtros['fecha_desde']; } // Filtro por Fecha Hasta if (!empty($filtros['fecha_hasta'])) { $sql .= " AND DATE(fecha) <= :fecha_hasta"; $params[':fecha_hasta'] = $filtros['fecha_hasta']; } // Ordenamiento $sql .= " ORDER BY id DESC"; // Límite if (!$verTodos) { $sql .= " LIMIT 300"; } // Preparar y ejecutar $stmt = $this->db->prepare($sql); $stmt->execute($params); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("AsistenciaModel ERROR en getRegistrosAsistencia: " . $e->getMessage()); return []; } } }