File "EmpleadoModel.php"

Full Path: C:/wamp64/www/AVIDOTAPP/models/EmpleadoModel.php
File size: 21.89 KB
MIME-type: text/x-php
Charset: utf-8

<?php
class EmpleadoModel {
    private $conexion;          // BD principal (avidotapp)
    private $conexionExterna;   // BD externa (almuerzo)

    public function __construct() {
        $database = new Database();
        $this->conexion         = $database->connect();
        $this->conexionExterna  = $database->connectExternal();
    }

    // ─── Datos para selects ────────────────────────────────────────
    
    /**
     * ✅ MODIFICADO: Centros de costo desde BD EXTERNA (almuerzo.ccosto)
     */
    public function getCentrosCosto() {
        // Intentar BD externa primero
        if ($this->conexionExterna) {
            $result = mysqli_query($this->conexionExterna,
                "SELECT Id_ccosto, D_ccosto FROM ccosto ORDER BY D_ccosto"
            );
            if ($result) {
                $rows = [];
                while ($r = mysqli_fetch_assoc($result)) $rows[] = $r;
                if (!empty($rows)) return $rows;  // Si tiene datos, úsalos
            }
        }
        
        // Fallback a BD principal si falla la externa
        $result = mysqli_query($this->conexion,
            "SELECT CCOSTO, DESCRIPCION FROM ccosto ORDER BY DESCRIPCION"
        );
        $rows = [];
        while ($r = mysqli_fetch_assoc($result)) $rows[] = $r;
        return $rows;
    }

    public function getAreas() {
        $result = mysqli_query($this->conexion, "SELECT * FROM area ORDER BY area");
        $rows = [];
        while ($r = mysqli_fetch_assoc($result)) $rows[] = $r;
        return $rows;
    }

    public function getCargos() {
        $result = mysqli_query($this->conexion, "SELECT * FROM cargo ORDER BY CARGO");
        $rows = [];
        while ($r = mysqli_fetch_assoc($result)) $rows[] = $r;
        return $rows;
    }

    public function getInventarioDisponible() {
        $result = mysqli_query($this->conexion,
            "SELECT CODIGO, DESCRIPCION, CANTIDAD FROM inventario WHERE CANTIDAD > 0 ORDER BY DESCRIPCION");
        $rows = [];
        while ($r = mysqli_fetch_assoc($result)) $rows[] = $r;
        return $rows;
    }

    // ─── NUEVO: Buscar empleado en BD EXTERNA (almuerzo.empleados) ─
    /**
     * ✅ NUEVO: Busca en BD externa primero (más actualizada)
     * Devuelve: cedula, nombre (concatenado), ccosto, cargo
     * Si no encuentra, busca en BD principal como fallback
     */
    public function buscarEmpleadoEnBDExterna($cedula) {
        if (!$this->conexionExterna) return null;
        
        $cedula_esc = mysqli_real_escape_string($this->conexionExterna, trim($cedula));
        $result = mysqli_query($this->conexionExterna,
            "SELECT cedula,
                    CONCAT(TRIM(nombre), ' ', TRIM(apellido)) AS nombre,
                    ccosto,
                    cargo
             FROM empleados
             WHERE cedula = '$cedula_esc'
             LIMIT 1"
        );
        
        if ($result && mysqli_num_rows($result) > 0) {
            return mysqli_fetch_assoc($result);
        }
        return null;
    }

    // ─── NUEVO: Buscar SOLO en BD interna (sin BD externa) ─────────
    /**
     * ✅ Busca ÚNICAMENTE en BD principal (avidotapp.empleado)
     * Usado para verificar si un empleado YA FUE REGISTRADO en el sistema interno
     * NO consulta BD externa (almuerzo)
     */
    public function buscarEmpleadoEnBDInterna($cedula) {
        $cedula_esc = mysqli_real_escape_string($this->conexion, trim($cedula));
        $result = mysqli_query($this->conexion,
            "SELECT * FROM empleado
             WHERE cedula = '$cedula_esc'
             ORDER BY id DESC
             LIMIT 1"
        );
        
        if ($result && mysqli_num_rows($result) > 0) {
            return mysqli_fetch_assoc($result);
        }
        return null;
    }

    /**
     * Busca ÚNICAMENTE registros en estado 'Pendiente' en BD interna.
     * Si existe un Pendiente → se le agregan EPP (no se crea nuevo registro).
     * Si no existe (o todos están 'Entregados') → se crea registro nuevo.
     */
    public function buscarEmpleadoPendienteEnBDInterna($cedula) {
        $cedula_esc = mysqli_real_escape_string($this->conexion, trim($cedula));
        $result = mysqli_query($this->conexion,
            "SELECT * FROM empleado
             WHERE cedula = '$cedula_esc' AND ESTADO = 'Pendiente'
             ORDER BY id DESC
             LIMIT 1"
        );

        if ($result && mysqli_num_rows($result) > 0) {
            return mysqli_fetch_assoc($result);
        }
        return null;
    }

    /**
     * Buscar un registro de empleado por su ID primario.
     * Usado para verificar el estado antes de agregar EPP.
     */
    public function buscarEmpleadoPorId($id) {
        $id = intval($id);
        $result = mysqli_query($this->conexion,
            "SELECT * FROM empleado WHERE id = $id LIMIT 1"
        );
        if ($result && mysqli_num_rows($result) > 0) {
            return mysqli_fetch_assoc($result);
        }
        return null;
    }

    // ─── MODIFICADO: Buscar último registro por cédula (autocompletar) ─
    /**
     * ✅ MODIFICADO: Busca primero en BD externa (datos frescos),
     *    luego complementa con BD principal (tallas, etc.)
     */
    public function buscarUltimoRegistroPorCedula($cedula) {
        $datosExternos = $this->buscarEmpleadoEnBDExterna($cedula);
        
        // Buscar en BD principal (para tallas, área, etc.) usando método específico
        $datosInternos = $this->buscarEmpleadoEnBDInterna($cedula) ?? [];
        
        // ✅ MERGE: Datos externos (más actuales) + datos internos (tallas)
        if ($datosExternos) {
            // Priorizar datos externos para: nombre, ccosto, cargo
            return array_merge($datosInternos, [
                'cedula'     => $datosExternos['cedula'],
                'nombre'     => $datosExternos['nombre'],   // nombre completo concatenado
                'ccosto'     => $datosExternos['ccosto'],
                'cargo'      => $datosExternos['cargo'],
                // Mantener tallas, área, etc. de BD interna
                'area'       => $datosInternos['area']       ?? '',
                'fingreso'   => $datosInternos['fingreso']   ?? date('Y-m-d'),
                'tallaPant'  => $datosInternos['tallaPant']  ?? $datosInternos['TALLAPANT']  ?? '',
                'tallaCami'  => $datosInternos['tallaCami']  ?? $datosInternos['TALLACAMI']  ?? '',
                'tallaBot'   => $datosInternos['tallaBot']   ?? $datosInternos['TALLABOT']   ?? '',
                'tallaChaq'  => $datosInternos['tallaChaq']  ?? $datosInternos['TALLACHAQ']  ?? '',
                'tallaImp'   => $datosInternos['tallaImp']   ?? $datosInternos['TALLAIMP']   ?? '',
                'tpEntrega'  => $datosInternos['tpEntrega']  ?? $datosInternos['TPENTREGA']  ?? '',
                'tpContrato' => $datosInternos['tpContrato'] ?? $datosInternos['TPCONTRATO'] ?? '',
                'id'         => $datosInternos['id']         ?? null,
            ]);
        }
        
        // Si no hay datos externos, devolver solo los internos
        return !empty($datosInternos) ? $datosInternos : null;
    }

    // ─── NUEVO: Todos los registros de una cédula (para consulta) ──────
    public function obtenerRegistrosPorCedula($cedula) {
        $cedula = mysqli_real_escape_string($this->conexion, trim($cedula));
        $result = mysqli_query($this->conexion,
            "SELECT e.*,
                    (SELECT GROUP_CONCAT(d.nombre_epp, ' (x', d.cantidad, ')' SEPARATOR ', ')
                     FROM dotacion d WHERE d.empleado_id = e.id) AS epp_lista
             FROM empleado e
             WHERE e.cedula = '$cedula'
             ORDER BY e.id DESC"
        );
        $rows = [];
        while ($r = mysqli_fetch_assoc($result)) $rows[] = $r;
        return $rows;
    }

    // ─── Insertar empleado + dotación ─────────────────────────────────
    public function insertarEmpleadoConDotacion($datosEmpleado, $dotaciones) {
        mysqli_autocommit($this->conexion, FALSE);
        try {
            $fingreso   = mysqli_real_escape_string($this->conexion, $datosEmpleado['fingreso']);
            $ident      = strtoupper(trim(mysqli_real_escape_string($this->conexion, $datosEmpleado['ident'])));
            $nombre     = strtoupper(trim(mysqli_real_escape_string($this->conexion, $datosEmpleado['nombre'])));
            $ccosto     = mysqli_real_escape_string($this->conexion, $datosEmpleado['ccosto']);
            $area       = mysqli_real_escape_string($this->conexion, $datosEmpleado['area']);
            $cargo      = mysqli_real_escape_string($this->conexion, $datosEmpleado['cargo']);
            $tallaPant  = strtoupper(trim(mysqli_real_escape_string($this->conexion, $datosEmpleado['tallaPant'])));
            $tallaCami  = strtoupper(trim(mysqli_real_escape_string($this->conexion, $datosEmpleado['tallaCami'])));
            $tallaBot   = strtoupper(trim(mysqli_real_escape_string($this->conexion, $datosEmpleado['tallaBot'])));
            $tallaChaq  = strtoupper(trim(mysqli_real_escape_string($this->conexion, $datosEmpleado['tallaChaq'])));
            $tallaImp   = strtoupper(trim(mysqli_real_escape_string($this->conexion, $datosEmpleado['tallaImp'])));
            $tpContrato = mysqli_real_escape_string($this->conexion, $datosEmpleado['tpContrato']);
            $tpEntrega  = mysqli_real_escape_string($this->conexion, $datosEmpleado['tpEntrega']);

            $q = "INSERT INTO empleado
                    (fingreso, cedula, nombre, ccosto, area, cargo,
                     tallaPant, tallaCami, tallaBot, tallaChaq, tallaImp,
                     tpContrato, ESTADO, tpEntrega)
                  VALUES
                    ('$fingreso','$ident','$nombre','$ccosto','$area','$cargo',
                     '$tallaPant','$tallaCami','$tallaBot','$tallaChaq','$tallaImp',
                     '$tpContrato','Pendiente','$tpEntrega')";

            if (!mysqli_query($this->conexion, $q))
                throw new Exception("Error al registrar empleado: " . mysqli_error($this->conexion));

            $empleado_id = mysqli_insert_id($this->conexion);
            if ($empleado_id <= 0)
                throw new Exception("No se pudo obtener el ID del empleado registrado.");

            $entregas_realizadas = 0;
            foreach ($dotaciones as $dot) {
                if (!empty($dot['descripcion']) && intval($dot['cantidad']) > 0) {
                    $desc   = mysqli_real_escape_string($this->conexion, $dot['descripcion']);
                    $cant   = intval($dot['cantidad']);
                    $codigo = isset($dot['codigo']) ? trim($dot['codigo']) : '';
                    
                    // Si codigo_epp es numérico (INT), no usar comillas
                    if (!empty($codigo) && is_numeric($codigo)) {
                        $codigo_int = intval($codigo);
                        $qd = "INSERT INTO dotacion (empleado_id, codigo_epp, nombre_epp, cantidad, fecha_entrega)
                               VALUES ($empleado_id, $codigo_int, '$desc', $cant, NOW())";
                    } else {
                        if (empty($codigo)) {
                            $qd = "INSERT INTO dotacion (empleado_id, codigo_epp, nombre_epp, cantidad, fecha_entrega)
                                   VALUES ($empleado_id, NULL, '$desc', $cant, NOW())";
                        } else {
                            $codigo_esc = mysqli_real_escape_string($this->conexion, $codigo);
                            $qd = "INSERT INTO dotacion (empleado_id, codigo_epp, nombre_epp, cantidad, fecha_entrega)
                                   VALUES ($empleado_id, '$codigo_esc', '$desc', $cant, NOW())";
                        }
                    }
                    if (!mysqli_query($this->conexion, $qd))
                        throw new Exception("Error al insertar dotación $desc: " . mysqli_error($this->conexion));
                    $entregas_realizadas++;
                }
            }

            mysqli_commit($this->conexion);
            return ['success' => true, 'empleado_id' => $empleado_id,
                    'nombre' => $nombre, 'entregas_realizadas' => $entregas_realizadas];

        } catch (Exception $e) {
            mysqli_rollback($this->conexion);
            return ['success' => false, 'error' => $e->getMessage()];
        } finally {
            mysqli_autocommit($this->conexion, TRUE);
        }
    }

    // ─── Validar datos ────────────────────────────────────────────────
    public function validarDatosEmpleado($datos) {
        $errores = [];
        if (empty($datos['fingreso'])) $errores[] = "La fecha de ingreso es obligatoria";
        if (empty($datos['ident']))    $errores[] = "La cédula es obligatoria";
        if (empty($datos['nombre']))   $errores[] = "El nombre es obligatorio";
        if (empty($datos['ccosto']))   $errores[] = "El centro de costo es obligatorio";
        if (empty($datos['area']))     $errores[] = "El área es obligatoria";
        if (empty($datos['cargo']))    $errores[] = "El cargo es obligatorio";
        if (empty($datos['tpEntrega']))  $errores[] = "El tipo de entrega es obligatorio";
        if (empty($datos['tpContrato'])) $errores[] = "El tipo de contrato es obligatorio";
        return $errores;
    }

    // ─── NUEVO: Agregar solo dotaciones a un empleado YA EXISTENTE ───
    /**
     * Usado cuando el empleado ya existe en BD y solo queremos agregar EPP.
     * Busca el ID del empleado por cédula y agrega las dotaciones.
     */
    public function agregarDotacionesSoloEPP($cedula, $dotaciones) {
        mysqli_autocommit($this->conexion, FALSE);
        try {
            $cedula_esc = mysqli_real_escape_string($this->conexion, trim($cedula));

            // Buscar ID del empleado
            $result = mysqli_query($this->conexion,
                "SELECT id, nombre FROM empleado WHERE cedula = '$cedula_esc' ORDER BY id DESC LIMIT 1"
            );
            if (!$result || mysqli_num_rows($result) == 0) {
                throw new Exception("No se encontró el empleado con cédula $cedula en la base de datos.");
            }
            $row = mysqli_fetch_assoc($result);
            $empleado_id = intval($row['id']);
            $nombre      = $row['nombre'];

            if ($empleado_id <= 0) {
                throw new Exception("ID de empleado inválido.");
            }

            // Insertar dotaciones
            $entregas_realizadas = 0;
            foreach ($dotaciones as $dot) {
                if (!empty($dot['descripcion']) && intval($dot['cantidad']) > 0) {
                    $desc   = mysqli_real_escape_string($this->conexion, $dot['descripcion']);
                    $cant   = intval($dot['cantidad']);
                    $codigo = isset($dot['codigo']) ? trim($dot['codigo']) : '';
                    
                    // Si codigo_epp es numérico (INT), no usar comillas
                    if (!empty($codigo) && is_numeric($codigo)) {
                        $codigo_int = intval($codigo);
                        $qd = "INSERT INTO dotacion (empleado_id, codigo_epp, nombre_epp, cantidad, fecha_entrega)
                               VALUES ($empleado_id, $codigo_int, '$desc', $cant, NOW())";
                    } else {
                        if (empty($codigo)) {
                            $qd = "INSERT INTO dotacion (empleado_id, codigo_epp, nombre_epp, cantidad, fecha_entrega)
                                   VALUES ($empleado_id, NULL, '$desc', $cant, NOW())";
                        } else {
                            $codigo_esc = mysqli_real_escape_string($this->conexion, $codigo);
                            $qd = "INSERT INTO dotacion (empleado_id, codigo_epp, nombre_epp, cantidad, fecha_entrega)
                                   VALUES ($empleado_id, '$codigo_esc', '$desc', $cant, NOW())";
                        }
                    }
                    if (!mysqli_query($this->conexion, $qd))
                        throw new Exception("Error al insertar dotación $desc: " . mysqli_error($this->conexion));
                    $entregas_realizadas++;
                }
            }

            mysqli_commit($this->conexion);
            return ['success' => true, 'empleado_id' => $empleado_id,
                    'nombre' => $nombre, 'entregas_realizadas' => $entregas_realizadas];

        } catch (Exception $e) {
            mysqli_rollback($this->conexion);
            return ['success' => false, 'error' => $e->getMessage()];
        } finally {
            mysqli_autocommit($this->conexion, TRUE);
        }
    }

    // ═══════════════════════════════════════════════════════════════
    // MÉTODOS DE EDICIÓN Y ELIMINACIÓN
    // ═══════════════════════════════════════════════════════════════

    /**
     * Agregar un EPP a la dotación de un empleado
     */
    public function agregarEPPADotacion($empleado_id, $codigo_epp, $nombre_epp, $cantidad) {
        $empleado_id = intval($empleado_id);
        $codigo_epp  = trim($codigo_epp);
        $nombre_epp  = mysqli_real_escape_string($this->conexion, $nombre_epp);
        $cantidad    = intval($cantidad);

        // Validar que codigo_epp no esté vacío
        if (empty($codigo_epp)) {
            return ['success' => false, 'error' => 'El código EPP es obligatorio'];
        }

        // Si codigo_epp es numérico (INTEGER), no usar comillas
        if (is_numeric($codigo_epp)) {
            $codigo_epp_int = intval($codigo_epp);
            $q = "INSERT INTO dotacion (empleado_id, codigo_epp, nombre_epp, cantidad, fecha_entrega)
                  VALUES ($empleado_id, $codigo_epp_int, '$nombre_epp', $cantidad, NOW())";
        } else {
            $codigo_epp_escaped = mysqli_real_escape_string($this->conexion, $codigo_epp);
            $q = "INSERT INTO dotacion (empleado_id, codigo_epp, nombre_epp, cantidad, fecha_entrega)
                  VALUES ($empleado_id, '$codigo_epp_escaped', '$nombre_epp', $cantidad, NOW())";
        }

        if (mysqli_query($this->conexion, $q)) {
            return ['success' => true, 'mensaje' => 'EPP agregado correctamente'];
        } else {
            return ['success' => false, 'error' => mysqli_error($this->conexion)];
        }
    }

    /**
     * Eliminar un EPP de la dotación
     */
    public function eliminarEPPDeDotacion($empleado_id, $nombre_epp) {
        $empleado_id = intval($empleado_id);
        $nombre_epp  = mysqli_real_escape_string($this->conexion, $nombre_epp);

        $q = "DELETE FROM dotacion 
              WHERE empleado_id = $empleado_id AND nombre_epp = '$nombre_epp'
              LIMIT 1";

        if (mysqli_query($this->conexion, $q)) {
            return ['success' => true, 'mensaje' => 'EPP eliminado correctamente'];
        } else {
            return ['success' => false, 'error' => mysqli_error($this->conexion)];
        }
    }

    /**
     * Actualizar cantidad de un EPP en la dotación
     */
    public function actualizarCantidadEPP($empleado_id, $nombre_epp, $cantidad) {
        $empleado_id = intval($empleado_id);
        $nombre_epp  = mysqli_real_escape_string($this->conexion, $nombre_epp);
        $cantidad    = intval($cantidad);

        $q = "UPDATE dotacion SET cantidad = $cantidad
              WHERE empleado_id = $empleado_id AND nombre_epp = '$nombre_epp'
              LIMIT 1";

        if (mysqli_query($this->conexion, $q)) {
            return ['success' => true, 'mensaje' => 'Cantidad actualizada correctamente'];
        } else {
            return ['success' => false, 'error' => mysqli_error($this->conexion)];
        }
    }

    /**
     * Eliminar completamente un registro de empleado y toda su dotación
     */
    public function eliminarRegistroCompleto($id) {
        $id = intval($id);
        mysqli_autocommit($this->conexion, FALSE);

        try {
            // Eliminar dotaciones asociadas
            $q1 = "DELETE FROM dotacion WHERE empleado_id = $id";
            if (!mysqli_query($this->conexion, $q1))
                throw new Exception("Error al eliminar dotaciones: " . mysqli_error($this->conexion));

            // Eliminar empleado
            $q2 = "DELETE FROM empleado WHERE id = $id";
            if (!mysqli_query($this->conexion, $q2))
                throw new Exception("Error al eliminar empleado: " . mysqli_error($this->conexion));

            mysqli_commit($this->conexion);
            return ['success' => true, 'mensaje' => 'Registro eliminado completamente'];

        } catch (Exception $e) {
            mysqli_rollback($this->conexion);
            return ['success' => false, 'error' => $e->getMessage()];
        } finally {
            mysqli_autocommit($this->conexion, TRUE);
        }
    }

    /**
     * Obtener EPP disponible desde la tabla inventario
     */
    public function getEPPDisponiblesParaAgregar() {
        $result = mysqli_query($this->conexion,
            "SELECT CODIGO, DESCRIPCION, CANTIDAD 
             FROM inventario 
             WHERE CANTIDAD > 0 
             ORDER BY DESCRIPCION"
        );
        
        if ($result) {
            $rows = [];
            while ($r = mysqli_fetch_assoc($result)) $rows[] = $r;
            return $rows;
        }
        
        return [];
    }
}
?>