File "AsistenciaModel.php"
Full Path: C:/wamp64/www/Asistencia_Capacitacion/Modelos/AsistenciaModel.php
File size: 12.67 KB
MIME-type: text/x-php
Charset: utf-8
<?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 [];
}
}
}