<?php

class AportanteController extends Controller{

	// Layout
	public $layout = 'panel';

	/**
	 * @return array action filters
	 */
	public function filters(){
		return array(
			'accessControl', // perform access control for CRUD operations
			'postOnly + delete', // we only allow deletion via POST request
		);
	}

	/**
	 * Specifies the access control rules.
	 * This method is used by the 'accessControl' filter.
	 * @return array access control rules
	 */
	public function accessRules(){
		return array(
			array(
				'allow',  // allow all users to perform 'index' and 'view' actions
				'actions' => array('index', 'view', 'obtenerDatos', 'modificar', 'eliminar','UpdateConciliacion','DeleteConciliacion','ActualizarAlicuotas','GuardarEstatus2009','EnviarCorreoIndividual','EnviarCorreosNoActualizados','cargarActividades','VerHistorial'),
				'users' => array('@'),
			),
			array(
				'deny',  // deny all users
				'users' => array('*'),
			),
		);
	}

	/*** Muestra todas los Aportantes ***/
	public function actionIndex(){
		$this->render('index');
	}

	/****	Muestra los datos del Aportante	***/
	public function actionView($id){
		$model = $this->loadModel($id);

		// Obtener alícuota actual (estatus 1)
	$modelAlicuotaAnt = SidcaiAporAlicuota::model()->findByAttributes([
		'cod_aportante' => $id,
		'estatus' => 1
	]);

	if (!$modelAlicuotaAnt) {
		$modelAlicuotaAnt = new SidcaiAporAlicuota();
	}

	// Descripción del tipo de empresa
	switch ($modelAlicuotaAnt->apor_tipoempresa) {
		case 1:
			$modelAlicuotaAnt->apor_tipoempresa = "Empresas contempladas en la Ley para el Control de los Casinos, Salas de Bingo y Máquinas Traganíqueles, y aquellas vinculadas con la producción, comercio y expendio de alcohol etílico, especies alcohólicas y tabaco.";
			break;
		case 2:
			$modelAlicuotaAnt->apor_tipoempresa = "Empresas de hidrocarburos y minería estratégica, tanto de capital privado como público, contempladas en la Ley Orgánica de Hidrocarburos, la Ley Orgánica de Hidrocarburos Gaseosos y el Decreto con Rango, Valor y Fuerza de Ley Orgánica que reserva al Estado las actividades de Exploración y Explotación del Oro y demás materiales estratégicos.";
			break;
		case 3:
			$modelAlicuotaAnt->apor_tipoempresa = "Empresas dedicadas a cualquier otra actividad económica no prevista en los numerales anteriores.";
			break;
	}

	// Obtener actividades económicas
	$actividadEconomica = $modelAlicuotaAnt->apor_actividad_economica;
	$actividadesEconomicas = [];

	if (!empty($actividadEconomica)) {
		$codigosActividades = array_map('intval', explode(',', $actividadEconomica));
		$actividadesEconomicas = SidcaiActividadEconomica::model()->findAll([
			'condition' => 'act_codigo_pk IN (' . implode(',', $codigosActividades) . ')'
		]);
	}

	// Cargar alícuota con estatus 4 (pendiente de verificación)
	$modelAlicuota = SidcaiAporAlicuota::model()->findByAttributes([
		'cod_aportante' => $id,
		'estatus' => 4
	]);

	if (!$modelAlicuota) {
		$modelAlicuota = new SidcaiAporAlicuota();
		$modelAlicuota->cod_aportante = $id;
	}

		// Se importa el Controlador para usar la función "convertirFecha"
		Yii::import('application.controllers.FuncionesController');

		$fecha_creacion_empresa = explode(" ", $model->apor_fechacreacionempresa);

		$model->apor_fechacreacionempresa = FuncionesController::convertirFecha($fecha_creacion_empresa[0], 'dd/mm/yyy');

		// Fecha Registro
		$fecha_registro = explode(" ", $model->apor_fechahoraregistro);

		$model->apor_fechahoraregistro = FuncionesController::convertirFecha($fecha_registro[0], 'dd/mm/yyy');
		$model->apor_fechahoraregistro .= " ".$fecha_registro[1];

		$model->ciiuCodigoFk->ciiu_porcentaje = FuncionesController::porcentajeContribucion($model->ciiu_codigo_fk);

		/** 
		Se verifica si el Aportante ha cambiado su Ejercicio Fiscal para obtener su última modificación de "Día" y "Mes".**/
		$existe = SidcaiEjercicioFiscal::model()->find(
			array(
				'condition' => 'apor_codigo_fk = :apor_codigo_fk',
				'params' => array(':apor_codigo_fk' => $id),
				'order' => 'ejercicio_fiscal_pk DESC',
			)
		);

		// Sí el aportante ha cambiado su Ejercicio Fiscal usará los datos del "SidcaiEjercicioFiscal".
		if($existe != null){
			$model->apor_diacierre = $existe->apor_diacierre;
			$model->apor_mescierre = $existe->apor_mescierre;
		}

		$this->render('view',array('model' => $model,'modelAlicuota' => $modelAlicuotaAnt));
	}	


	// En tu controlador, por ejemplo, SiteController.php
	public function actionCargarActividades()
	{
		$tipoEmpresa = Yii::app()->request->getParam('tipo_empresa');
		$actividades = array();
	
		if ($tipoEmpresa) {
			// Consulta a la base de datos para obtener las actividades según el tipo de empresa
			$criteria = new CDbCriteria();
			$criteria->condition = 'act_tipoempresa_fk = :tipo_empresa';
			$criteria->params = array(':tipo_empresa' => $tipoEmpresa);
			$criteria->params = array(':tipo_empresa' => $tipoEmpresa);
			$criteria->order = 'act_nombre ASC';
			
			$modelos = SidcaiActividadEconomica::model()->findAll($criteria);
			
			foreach ($modelos as $modelo) {
				$actividades[$modelo->act_codigo_pk] = $modelo->act_nombre;
			}
		}
	
		echo CJSON::encode($actividades);
		Yii::app()->end();
	}



	public function actionModificar711($id)
{
    $model = $this->loadModel($id);
    $model->scenario = "modificar";

    $this->performAjaxValidation($model);

    // Guardamos los valores actuales para detectar cambios
    $oldAportanteAttrs = $model->getAttributes([
        'apor_razonsocial', 'apor_denominacion', 'esta_codigo_fk', 'apor_actividad_principal'
    ]);

    // Alícuota existente activa
    $alicuotaExistente = SidcaiAporAlicuota::model()->find(array(
        'condition' => 'cod_aportante = :apor AND estatus = 1',
        'params' => [':apor' => $model->apor_codigo_pk],
        'order' => 'fecha_registro DESC'
    ));

    if (isset($_POST['SidcaiAportante'])) {
        $transaction = Yii::app()->db->beginTransaction();
        $response = [];

        try {
            // -------------------------
            // 1) Actualizar APORTANTE
            // -------------------------
            $model->attributes = $_POST['SidcaiAportante'];
            if (isset($_POST['SidcaiAportante']['apor_correoelectronico']) && strpos($_POST['SidcaiAportante']['apor_correoelectronico'], '@') === false) {
                $model->apor_correoelectronico = $_POST['SidcaiAportante']['apor_correoelectronico'] . '@gmail.com';
            }

            $model->apor_fechahoramodif = new CDbExpression('NOW()');

            if (!$model->save(false)) {
                throw new CException('Error guardando aportante: ' . print_r($model->getErrors(), true));
            }

            // -------------------------
            // 2) PROCESAR ALÍCUOTA
            // -------------------------
            if (isset($_POST['SidcaiAporAlicuota'])) {
                $alicuotaData = $_POST['SidcaiAporAlicuota'];

                // Normalizar datos
                if (isset($alicuotaData['apor_actividad_economica'])) {
                    if (is_array($alicuotaData['apor_actividad_economica'])) {
                        $tmp = array_filter(array_map('trim', $alicuotaData['apor_actividad_economica']));
                        $alicuotaData['apor_actividad_economica'] = implode(',', $tmp);
                    } else {
                        $alicuotaData['apor_actividad_economica'] = trim($alicuotaData['apor_actividad_economica']);
                    }
                } else {
                    $alicuotaData['apor_actividad_economica'] = '';
                }

                $alicuotaData['es_fidetel'] = isset($alicuotaData['es_fidetel']) ? 1 : 0;
                $alicuotaData['apor_porcprivada'] = floatval($alicuotaData['apor_porcprivada'] ?? 0.0);
                $alicuotaData['apor_porcpublico'] = floatval($alicuotaData['apor_porcpublico'] ?? 0.0);
                $alicuotaData['alicuota'] = floatval($alicuotaData['alicuota'] ?? 0.0);

                // -------------------------
                // 3) DETECTAR CAMBIOS
                // -------------------------
                $aportanteCambio = false;
                foreach (['apor_razonsocial', 'apor_denominacion', 'esta_codigo_fk', 'apor_actividad_principal'] as $campo) {
                    $old = trim((string)($oldAportanteAttrs[$campo] ?? ''));
                    $new = trim((string)($_POST['SidcaiAportante'][$campo] ?? $old));
                    if ($old !== $new) {
                        $aportanteCambio = true;
                        break;
                    }
                }

                $alicuotaCambioDetectada = false;
                if ($alicuotaExistente) {
                    $alicuotaCambioDetectada = $this->alicuotaCambio($alicuotaExistente, $alicuotaData);
                } else {
                    $alicuotaCambioDetectada = true;
                    Yii::log("No existía alícuota activa, se creará nueva.", 'info');
                }

                // -------------------------
                // 4) ACTUAR SEGÚN CAMBIO
                // -------------------------
                if ($aportanteCambio || $alicuotaCambioDetectada) {
                    // Desactivar alícuota anterior
                    if ($alicuotaExistente) {
                        $alicuotaExistente->estatus = 3;
                        $alicuotaExistente->fecha_modificacion = new CDbExpression('NOW()');
                        if (!$alicuotaExistente->save(false)) {
                            throw new CException('Error desactivando alícuota anterior.');
                        }
                    }

                    // Crear nueva
                    $nueva = new SidcaiAporAlicuota();
                    $nueva->cod_aportante = $model->apor_codigo_pk;
                    $nueva->apor_tipoempresa = $alicuotaData['apor_tipoempresa'] ?? null;
                    $nueva->apor_actividad_economica = $alicuotaData['apor_actividad_economica'];
                    $nueva->es_fidetel = $alicuotaData['es_fidetel'];
                    $nueva->apor_porcprivada = $alicuotaData['apor_porcprivada'];
                    $nueva->apor_porcpublico = $alicuotaData['apor_porcpublico'];
                    $nueva->alicuota = $alicuotaData['alicuota'];
                    $nueva->fecha_registro = new CDbExpression('NOW()');
                    $nueva->fecha_modificacion = new CDbExpression('NOW()');
                    $nueva->estatus = 1;

                    if (!$nueva->save()) {
                        throw new CException('Error creando nueva alícuota: ' . print_r($nueva->getErrors(), true));
                    }

                    $response['alicuota'] = 'Nueva alícuota creada. Anterior desactivada.';
                } else {
                    // No hubo cambios significativos -> actualizar la actual
                    if ($alicuotaExistente) {
                        foreach ($alicuotaData as $k => $v) {
                            if ($alicuotaExistente->hasAttribute($k)) {
                                $alicuotaExistente->$k = $v;
                            }
                        }
                        $alicuotaExistente->fecha_modificacion = new CDbExpression('NOW()');
                        if (!$alicuotaExistente->save(false)) {
                            throw new CException('Error actualizando alícuota existente.');
                        }
                    }
                    $response['alicuota'] = 'Alícuota actual actualizada (sin cambios relevantes).';
                }
            }

            // -------------------------
            // 5) MARCAR APORTANTE ACTUALIZADO
            // -------------------------
            $model->datos_actualizados = 1;
            $model->apor_fechahoramodif = new CDbExpression('NOW()');
            $model->save(false);

            $transaction->commit();
            $response['status'] = 'success';
            echo json_encode($response);
            Yii::app()->end();

        } catch (Exception $e) {
            $transaction->rollback();
            Yii::log("Error en actionModificar: " . $e->getMessage(), 'error');
            echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
            Yii::app()->end();
        }
    }

    // -------------------------
    // 6) MODO GET (Render Vista)
    // -------------------------
    Yii::import('application.controllers.FuncionesController');

    $model->apor_fechacreacionempresa = FuncionesController::convertirFecha($model->apor_fechacreacionempresa, 'dd/mm/yyyy', false);
    $model->apor_fechahoraregistro = FuncionesController::convertirFecha($model->apor_fechahoraregistro, 'dd/mm/yyyy');

    $correo = explode("@", $model->apor_correoelectronico);
    $model->apor_correoelectronico = $correo[0] ?? $model->apor_correoelectronico;
    $model->tipo_documento = substr($model->apor_rif, 0, 1);
	
    $model->apor_rif = substr($model->apor_rif, 1, 9);


    // Ajustar booleanos
    $model->apor_habilitado = ($model->apor_habilitado) ? 1 : 0;
    $model->estatus_conciliacion = ($model->estatus_conciliacion) ? 1 : 0;
	$model->datos_actualizados = ($model->datos_actualizados) ? 1 : 0;



    $modelAlicuota = $alicuotaExistente ?: new SidcaiAporAlicuota();
    $modelAlicuota->cod_aportante = $model->apor_codigo_pk;
    $modelAlicuota->alicuota_actual = $alicuotaExistente ? $alicuotaExistente->alicuota : 0;

    $representantes = CHtml::listData(
        SidcaiRepresentantelegal::model()->findAll(),
        'repr_codigo_pk',
        function ($data) {
            return $data->repr_documento . ' - ' . $data->repr_nombres . ' ' . $data->repr_apellidos;
        }
    );

    $conciliaciones = SidcaiCasillasIslr::model()->with('estatusFk')->findAll([
        'condition' => 'apor_codigo_fk = :apor',
        'params' => [':apor' => $id],
    ]);

    $this->render('guardar', [
        'model' => $model,
        'modelAlicuota' => $modelAlicuota,
        'conciliaciones' => $conciliaciones,
        'representantes' => $representantes
    ]);
}


/**
 * Detecta si hubo cambio significativo entre la alícuota existente y los nuevos datos.
 */
private function alicuotaCambio711($alicuotaExistente, $nuevosDatos)
{
    $tolerancia = 0.01;

    $nuevosDatos = array_map(function($v) {
        return is_string($v) ? trim($v) : $v;
    }, $nuevosDatos);

    if ((string)$alicuotaExistente->apor_tipoempresa !== (string)($nuevosDatos['apor_tipoempresa'] ?? '')) return true;

    $existAct = array_filter(array_map('trim', explode(',', (string)$alicuotaExistente->apor_actividad_economica)));
    $newAct = array_filter(array_map('trim', explode(',', (string)($nuevosDatos['apor_actividad_economica'] ?? ''))));
    sort($existAct); sort($newAct);
    if ($existAct !== $newAct) return true;

    if ((int)$alicuotaExistente->es_fidetel !== (int)($nuevosDatos['es_fidetel'] ?? 0)) return true;

    if (abs(floatval($alicuotaExistente->apor_porcprivada) - floatval($nuevosDatos['apor_porcprivada'] ?? 0)) > $tolerancia) return true;
    if (abs(floatval($alicuotaExistente->apor_porcpublico) - floatval($nuevosDatos['apor_porcpublico'] ?? 0)) > $tolerancia) return true;
    if (abs(floatval($alicuotaExistente->alicuota) - floatval($nuevosDatos['alicuota'] ?? 0)) > $tolerancia) return true;

    return false;
}




	public function actionModificar611($id){
		$model = $this->loadModel($id);
		$model->scenario = "modificar";

		// Inicializar $modelAlicuota con valor por defecto
		$modelAlicuota = new SidcaiAporAlicuota();
	
		// Verificar y cargar alícuota existente si corresponde
		if ($model->alicuotaActual !== null) {
			$modelAlicuota = $model->alicuotaActual;
		}
	
		// Asignar código de aportante si es nuevo
		$modelAlicuota->cod_aportante = $model->apor_codigo_pk;

		$this->performAjaxValidation($model);

		if(isset($_POST['SidcaiAportante'])){
			if(isset($_POST['ok'])){			
				$data = null; // Variable que sera enviada por JSON

				$data['datos'] = $this->guardar($model, $_POST['SidcaiAportante'], "modificar", $id);

				echo json_encode($data);
			}
			Yii::app()->end();
		}else{
			$date = new DateTime("now", new DateTimeZone('America/Caracas'));
			// Se importa el Controlador para usar la función "convertirFecha"
			Yii::import('application.controllers.FuncionesController');
			$model->apor_fechacreacionempresa = FuncionesController::convertirFecha($model->apor_fechacreacionempresa, 'dd/mm/yyy', false);
			$model->apor_fechahoraregistro = FuncionesController::convertirFecha($model->apor_fechahoraregistro, 'dd/mm/yyy');

			// Correo electrónico
			$correo = explode("@", $model->apor_correoelectronico);
			$model->apor_correoelectronico = $correo[0];

			// Tipo documento
			$model->tipo_documento = substr($model->apor_rif, 0, 1);

			// Número de RIF
			$model->apor_rif = substr($model->apor_rif, 1, 9);

			$model->apor_habilitado = ($model->apor_habilitado) ? 1 : 0;

			$model->estatus_conciliacion = ($model->estatus_conciliacion) ? 1 : 0;

			/**Se verifica si el Aportante ha cambiado su Ejercicio Fiscal para obtener su última modificación de "Día" y "Mes".**/
			$existe = SidcaiEjercicioFiscal::model()->find(
				array(
					'condition' => 'apor_codigo_fk = :apor_codigo_fk',
					'params' => array(':apor_codigo_fk' => $id),
					'order' => 'ejercicio_fiscal_pk DESC',
				)
			);

			// Sí el aportante ha cambiado su Ejercicio Fiscal usará los datos del "SidcaiEjercicioFiscal".
			if($existe != null){
				$model->apor_diacierre = $existe->apor_diacierre;
				$model->apor_mescierre = $existe->apor_mescierre;
			}

			$conciliaciones = SidcaiCasillasIslr::model()->with('estatusFk')->findAll(
				array(
					'condition' => 'apor_codigo_fk = :apor_codigo',
					'params' => array(
						':apor_codigo' => $id,
					),
				)
			);

			// Obtener modelo de alícuota activa (estatus = 1) más reciente
		$modelAlicuota = SidcaiAporAlicuota::model()->findByAttributes(
			array(
				'cod_aportante' => $model->apor_codigo_pk,
				'estatus' => 1 // Asegura que solo traiga registros con estatus = 1
			),
			array('order' => 'fecha_registro DESC') // Ordena por fecha descendente para obtener la más reciente
		);
	
		// Si no existe alícuota activa, crear una nueva instancia
		if (!$modelAlicuota) {
			$modelAlicuota = new SidcaiAporAlicuota();
			$modelAlicuota->cod_aportante = $model->apor_codigo_pk;
			//$modelAlicuota->estatus = 1; // Establecer estatus = 1 por defecto
		}

		// Obtener el valor actual de la alícuota desde la base de datos
		$alicuotaActual = SidcaiAporAlicuota::model()->findByAttributes(
			array(
				'cod_aportante' => $model->apor_codigo_pk,
				'estatus' => 1 // Asegura que solo traiga registros con estatus = 1
			),
			array('order' => 'fecha_registro DESC') // Ordena por fecha descendente para obtener la más reciente
		);

		if ($alicuotaActual !== null) {
			$modelAlicuota->alicuota_actual = $alicuotaActual->alicuota; // Asumiendo que 'valor' es el atributo que contiene el valor de la alícuota
		} else {
			$modelAlicuota->alicuota_actual = 0; // Valor por defecto si no se encuentra ninguna alícuota con estatus 1
		}

		  // 🔹 Obtener lista de representantes legales para el dropdown
       $representantes = CHtml::listData(
			SidcaiRepresentantelegal::model()->findAll(),
			'repr_codigo_pk',
			function($data) {
				return $data->repr_documento . ' - ' . $data->repr_nombres . ' ' . $data->repr_apellidos;
			}
		);
	

			$this->render('guardar', 
				array(
					'model' => $model,
					'modelAlicuota' => $modelAlicuota,
					'conciliaciones' => $conciliaciones,
					'representantes' => $representantes // 👈 Se pasa al formulario
				)
			);
		}
	}

	public function actionModificarfinal($id) {
    $model = $this->loadModel($id);
    $model->scenario = "modificar";

    // Inicializar alícuota
    $alicuotaExistente = SidcaiAporAlicuota::model()->findByAttributes(
        ['cod_aportante' => $model->apor_codigo_pk, 'estatus' => 1],
        ['order' => 'fecha_registro DESC']
    );
    $modelAlicuota = $alicuotaExistente ?: new SidcaiAporAlicuota();
    $modelAlicuota->cod_aportante = $model->apor_codigo_pk;
    $modelAlicuota->alicuota_actual = $alicuotaExistente ? $alicuotaExistente->alicuota : 0;

    $this->performAjaxValidation($model);

    if (isset($_POST['SidcaiAportante']) && isset($_POST['ok'])) {

        $transaction = Yii::app()->db->beginTransaction();
        try {
            // -------------------------
            // 1) Guardar aportante
            // -------------------------
            $rifCompleto = trim($_POST['SidcaiAportante']['tipo_documento']) . trim($_POST['SidcaiAportante']['apor_rif']);
            $_POST['SidcaiAportante']['apor_rif'] = $rifCompleto;

            $model->attributes = $_POST['SidcaiAportante'];

            // Validar correo
            if (!empty($model->apor_correoelectronico) && strpos($model->apor_correoelectronico, '@') === false) {
                $model->apor_correoelectronico .= '@gmail.com';
            }

            $model->datos_actualizados = 1;
            $model->apor_fechahoramodif = new CDbExpression('NOW()');

            if (!$model->save(false)) {
                throw new CException('Error guardando aportante: ' . print_r($model->getErrors(), true));
            }

            // -------------------------
            // 2) Guardar alícuota
            // -------------------------
            if (isset($_POST['SidcaiAporAlicuota'])) {
                $alicuotaData = $_POST['SidcaiAporAlicuota'];

                // Normalizar datos
                if (isset($alicuotaData['apor_actividad_economica']) && is_array($alicuotaData['apor_actividad_economica'])) {
                    $tmp = array_filter(array_map('trim', $alicuotaData['apor_actividad_economica']));
                    $alicuotaData['apor_actividad_economica'] = implode(',', $tmp);
                }

                $alicuotaData['es_fidetel'] = isset($alicuotaData['es_fidetel']) && $alicuotaData['es_fidetel'] ? 1 : 0;
                $alicuotaData['apor_porcprivada'] = floatval($alicuotaData['apor_porcprivada'] ?? 0);
                $alicuotaData['apor_porcpublico'] = floatval($alicuotaData['apor_porcpublico'] ?? 0);
                $alicuotaData['alicuota'] = floatval($alicuotaData['alicuota'] ?? 0);

                $crearNueva = false;

                if ($alicuotaExistente) {
                    $crearNueva = $this->alicuotaCambio($alicuotaExistente, $alicuotaData);
                } else {
                    $crearNueva = true;
                }

                if ($crearNueva) {
                    // Desactivar anterior
                    if ($alicuotaExistente) {
                        $alicuotaExistente->estatus = 3;
                        $alicuotaExistente->fecha_modificacion = new CDbExpression('NOW()');
                        if (!$alicuotaExistente->save(false)) {
                            throw new CException('Error desactivando alícuota anterior.');
                        }
                    }

                    // Crear nueva alícuota
                    $nueva = new SidcaiAporAlicuota();
                    $nueva->cod_aportante = $model->apor_codigo_pk;

                    foreach ($alicuotaData as $k => $v) {
                        if ($nueva->hasAttribute($k)) {
                            $nueva->$k = $v;
                        }
                    }

                    $nueva->estatus = 1;
                    $nueva->fecha_registro = new CDbExpression('NOW()');
                    $nueva->fecha_modificacion = new CDbExpression('NOW()');
                    
                    // ✅ Agregar comentario automático
                    $nueva->comentarios = 'Actualización por parte del usuario administrador';

                    if (!$nueva->save(false)) {
                        throw new CException('Error creando nueva alícuota: ' . print_r($nueva->getErrors(), true));
                    }
                } else {
                    // Actualizar existente
                    foreach ($alicuotaData as $k => $v) {
                        if ($alicuotaExistente->hasAttribute($k)) {
                            $alicuotaExistente->$k = $v;
                        }
                    }
                    $alicuotaExistente->fecha_modificacion = new CDbExpression('NOW()');
                    if (!$alicuotaExistente->save(false)) {
                        throw new CException('Error actualizando alícuota existente: ' . print_r($alicuotaExistente->getErrors(), true));
                    }
                }
            }

            $transaction->commit();

            echo json_encode([
                'datos' => [
                    'success',
                    'Aportante y alícuota guardados correctamente',
                    'modificar',
                    '',
                    'redirigir'
                ]
            ]);
            Yii::app()->end();

        } catch (Exception $e) {
            $transaction->rollback();
            echo json_encode([
                'datos' => [
                    'error',
                    'Ocurrió un error: ' . $e->getMessage(),
                    '',
                    '',
                    ''
                ]
            ]);
            Yii::app()->end();
        }
    }

    // -------------------------
    // GET: Preparar datos para la vista
    // -------------------------
    Yii::import('application.controllers.FuncionesController');
    $model->apor_fechacreacionempresa = FuncionesController::convertirFecha($model->apor_fechacreacionempresa, 'dd/mm/yyyy', false);
    $model->apor_fechahoraregistro = FuncionesController::convertirFecha($model->apor_fechahoraregistro, 'dd/mm/yyyy');

    // RIF separado para mostrar
    $model->tipo_documento = substr($model->apor_rif, 0, 1);
    $model->apor_rif = substr($model->apor_rif, 1);

    $model->apor_habilitado = $model->apor_habilitado ? 1 : 0;
    $model->estatus_conciliacion = $model->estatus_conciliacion ? 1 : 0;
    $model->datos_actualizados = $model->datos_actualizados ? 1 : 0;

    $conciliaciones = SidcaiCasillasIslr::model()->with('estatusFk')->findAll([
        'condition' => 'apor_codigo_fk = :apor',
        'params' => [':apor' => $id],
    ]);

    $representantes = CHtml::listData(
        SidcaiRepresentantelegal::model()->findAll(),
        'repr_codigo_pk',
        function ($data) {
            return $data->repr_documento . ' - ' . $data->repr_nombres . ' ' . $data->repr_apellidos;
        }
    );

    $this->render('guardar', [
        'model' => $model,
        'modelAlicuota' => $modelAlicuota,
        'conciliaciones' => $conciliaciones,
        'representantes' => $representantes
    ]);
}


public function actionModificar($id)
{
    $model = $this->loadModel($id);
    $model->scenario = "modificar";

    // Inicializar alícuota
    $alicuotaExistente = SidcaiAporAlicuota::model()->findByAttributes(
        ['cod_aportante' => $model->apor_codigo_pk, 'estatus' => 1],
        ['order' => 'fecha_registro DESC']
    );
    $modelAlicuota = $alicuotaExistente ?: new SidcaiAporAlicuota();
    $modelAlicuota->cod_aportante = $model->apor_codigo_pk;
    $modelAlicuota->alicuota_actual = $alicuotaExistente ? $alicuotaExistente->alicuota : 0;

    $this->performAjaxValidation($model);

    if (isset($_POST['SidcaiAportante']) && isset($_POST['ok'])) {

        $transaction = Yii::app()->db->beginTransaction();
        try {
            // -------------------------
            // 1) Guardar aportante
            // -------------------------
            $rifCompleto = trim($_POST['SidcaiAportante']['tipo_documento']) . trim($_POST['SidcaiAportante']['apor_rif']);
            $_POST['SidcaiAportante']['apor_rif'] = $rifCompleto;

            $model->attributes = $_POST['SidcaiAportante'];

            // ✅ Validar y formatear correo
            if (!empty($model->apor_correoelectronico)) {
                // Si no contiene '@', agregar dominio
                if (strpos($model->apor_correoelectronico, '@') === false) {
                    $model->apor_correoelectronico .= '@gmail.com';
                }
                // Guardar en mayúsculas
                $model->apor_correoelectronico = strtoupper($model->apor_correoelectronico);
            }

            $model->datos_actualizados = 1;
            $model->apor_fechahoramodif = new CDbExpression('NOW()');

            if (!$model->save(false)) {
                throw new CException('Error guardando aportante: ' . print_r($model->getErrors(), true));
            }

            // -------------------------
            // 2) Guardar ejercicio fiscal (NUEVO)
            // -------------------------
            if (isset($_POST['SidcaiAportante']['apor_diacierre']) && isset($_POST['SidcaiAportante']['apor_mescierre'])) {
                $dia = intval($_POST['SidcaiAportante']['apor_diacierre']);
                $mes = intval($_POST['SidcaiAportante']['apor_mescierre']);

                // Validaciones
                if ($dia < 1 || $dia > 31) {
                    throw new CException('El día de cierre debe estar entre 1 y 31');
                }

                if ($mes < 1 || $mes > 12) {
                    throw new CException('El mes de cierre debe estar entre 1 y 12');
                }

                // ACTUALIZAR SidcaiAportante
                $model->apor_diacierre = $dia;
                $model->apor_mescierre = $mes;
                
                if (!$model->save(false)) {
                    throw new CException('Error actualizando cierre fiscal en aportante.');
                }

                // INSERTAR nuevo registro en SidcaiEjercicioFiscal
                $ejercicioFiscal = new SidcaiEjercicioFiscal();
                $ejercicioFiscal->apor_diacierre = $dia;
                $ejercicioFiscal->apor_mescierre = $mes;
                $ejercicioFiscal->estatus = 1;
                $ejercicioFiscal->apor_codigo_fk = $model->apor_codigo_pk;
                $ejercicioFiscal->fecha_actualizacion = new CDbExpression('NOW()');

                if (!$ejercicioFiscal->save(false)) {
                    throw new CException('Error guardando historial de ejercicio fiscal.');
                }
            }

            // -------------------------
            // 3) Guardar alícuota
            // -------------------------
            if (isset($_POST['SidcaiAporAlicuota'])) {
                $alicuotaData = $_POST['SidcaiAporAlicuota'];

                if (isset($alicuotaData['apor_actividad_economica']) && is_array($alicuotaData['apor_actividad_economica'])) {
                    $tmp = array_filter(array_map('trim', $alicuotaData['apor_actividad_economica']));
                    $alicuotaData['apor_actividad_economica'] = implode(',', $tmp);
                }

                $alicuotaData['es_fidetel'] = isset($alicuotaData['es_fidetel']) && $alicuotaData['es_fidetel'] ? 1 : 0;
                $alicuotaData['apor_porcprivada'] = floatval($alicuotaData['apor_porcprivada'] ?? 0);
                $alicuotaData['apor_porcpublico'] = floatval($alicuotaData['apor_porcpublico'] ?? 0);
                $alicuotaData['alicuota'] = floatval($alicuotaData['alicuota'] ?? 0);

                $crearNueva = false;
                if ($alicuotaExistente) {
                    $crearNueva = $this->alicuotaCambio($alicuotaExistente, $alicuotaData);
                } else {
                    $crearNueva = true;
                }

                if ($crearNueva) {
                    if ($alicuotaExistente) {
                        $alicuotaExistente->estatus = 3;
                        $alicuotaExistente->fecha_modificacion = new CDbExpression('NOW()');
                        if (!$alicuotaExistente->save(false)) {
                            throw new CException('Error desactivando alícuota anterior.');
                        }
                    }

                    $nueva = new SidcaiAporAlicuota();
                    $nueva->cod_aportante = $model->apor_codigo_pk;
                    foreach ($alicuotaData as $k => $v) {
                        if ($nueva->hasAttribute($k)) {
                            $nueva->$k = $v;
                        }
                    }
                    $nueva->estatus = 1;
                    $nueva->fecha_registro = new CDbExpression('NOW()');
                    $nueva->fecha_modificacion = new CDbExpression('NOW()');
                    $nueva->comentarios = 'Actualización por parte del usuario administrador';

                    if (!$nueva->save(false)) {
                        throw new CException('Error creando nueva alícuota: ' . print_r($nueva->getErrors(), true));
                    }
                } else {
                    foreach ($alicuotaData as $k => $v) {
                        if ($alicuotaExistente->hasAttribute($k)) {
                            $alicuotaExistente->$k = $v;
                        }
                    }
                    $alicuotaExistente->fecha_modificacion = new CDbExpression('NOW()');
                    if (!$alicuotaExistente->save(false)) {
                        throw new CException('Error actualizando alícuota existente: ' . print_r($alicuotaExistente->getErrors(), true));
                    }
                }
            }

            $transaction->commit();

            echo json_encode([
                'datos' => ['success', 'Aportante, ejercicio fiscal y alícuota guardados correctamente', 'modificar', '', 'redirigir']
            ]);
            Yii::app()->end();

        } catch (Exception $e) {
            $transaction->rollback();
            echo json_encode([
                'datos' => ['error', 'Ocurrió un error: ' . $e->getMessage(), '', '', '']
            ]);
            Yii::app()->end();
        }
    }

    // -------------------------
    // GET: Preparar datos para la vista
    // -------------------------
    Yii::import('application.controllers.FuncionesController');
    $model->apor_fechacreacionempresa = FuncionesController::convertirFecha($model->apor_fechacreacionempresa, 'dd/mm/yyyy', false);
    $model->apor_fechahoraregistro = FuncionesController::convertirFecha($model->apor_fechahoraregistro, 'dd/mm/yyyy');

    // RIF separado para mostrar
    $model->tipo_documento = substr($model->apor_rif, 0, 1);
    $model->apor_rif = substr($model->apor_rif, 1);

    // ✅ Mostrar solo el correo antes del '@' en la vista
    if (!empty($model->apor_correoelectronico) && strpos($model->apor_correoelectronico, '@') !== false) {
        $correo = explode('@', $model->apor_correoelectronico);
        $model->apor_correoelectronico = $correo[0];
    }

    $model->apor_habilitado = $model->apor_habilitado ? 1 : 0;
    $model->estatus_conciliacion = $model->estatus_conciliacion ? 1 : 0;
    $model->datos_actualizados = $model->datos_actualizados ? 1 : 0;

    // Cargar el último ejercicio fiscal para mostrar en la vista
    $ejercicioFiscalActual = SidcaiEjercicioFiscal::model()->find([
        'condition' => 'apor_codigo_fk = :apor',
        'params' => [':apor' => $model->apor_codigo_pk],
        'order' => 'ejercicio_fiscal_pk DESC'
    ]);

    // CARGAR DATOS DEL EJERCICIO FISCAL EN EL MODELO PARA LA VISTA
    if ($ejercicioFiscalActual) {
        $model->apor_diacierre = $ejercicioFiscalActual->apor_diacierre;
        $model->apor_mescierre = $ejercicioFiscalActual->apor_mescierre;
    } else {
        // Si no hay registro histórico, usar los valores actuales del aportante
        $model->apor_diacierre = $model->apor_diacierre;
        $model->apor_mescierre = $model->apor_mescierre;
    }

    // Asegurar que los valores sean numéricos para los dropdowns
    $model->apor_diacierre = $model->apor_diacierre ? intval($model->apor_diacierre) : null;
    $model->apor_mescierre = $model->apor_mescierre ? intval($model->apor_mescierre) : null;

    $conciliaciones = SidcaiCasillasIslr::model()->with('estatusFk')->findAll([
        'condition' => 'apor_codigo_fk = :apor',
        'params' => [':apor' => $id],
    ]);

    $representantes = CHtml::listData(
        SidcaiRepresentantelegal::model()->findAll(),
        'repr_codigo_pk',
        function ($data) {
            return $data->repr_documento . ' - ' . $data->repr_nombres . ' ' . $data->repr_apellidos;
        }
    );

    $this->render('guardar', [
        'model' => $model,
        'modelAlicuota' => $modelAlicuota,
        'conciliaciones' => $conciliaciones,
        'representantes' => $representantes
    ]);
}

public function actionModificar20112025($id)
{
    $model = $this->loadModel($id);
    $model->scenario = "modificar";

    // Inicializar alícuota
    $alicuotaExistente = SidcaiAporAlicuota::model()->findByAttributes(
        ['cod_aportante' => $model->apor_codigo_pk, 'estatus' => 1],
        ['order' => 'fecha_registro DESC']
    );
    $modelAlicuota = $alicuotaExistente ?: new SidcaiAporAlicuota();
    $modelAlicuota->cod_aportante = $model->apor_codigo_pk;
    $modelAlicuota->alicuota_actual = $alicuotaExistente ? $alicuotaExistente->alicuota : 0;

    $this->performAjaxValidation($model);

    if (isset($_POST['SidcaiAportante']) && isset($_POST['ok'])) {

        $transaction = Yii::app()->db->beginTransaction();
        try {
            // -------------------------
            // 1) Guardar aportante
            // -------------------------
            $rifCompleto = trim($_POST['SidcaiAportante']['tipo_documento']) . trim($_POST['SidcaiAportante']['apor_rif']);
            $_POST['SidcaiAportante']['apor_rif'] = $rifCompleto;

            $model->attributes = $_POST['SidcaiAportante'];

            // ✅ Validar y formatear correo
            if (!empty($model->apor_correoelectronico)) {
                // Si no contiene '@', agregar dominio
                if (strpos($model->apor_correoelectronico, '@') === false) {
                    $model->apor_correoelectronico .= '@gmail.com';
                }
                // Guardar en mayúsculas
                $model->apor_correoelectronico = strtoupper($model->apor_correoelectronico);
            }

            $model->datos_actualizados = 1;
            $model->apor_fechahoramodif = new CDbExpression('NOW()');

            if (!$model->save(false)) {
                throw new CException('Error guardando aportante: ' . print_r($model->getErrors(), true));
            }

            // -------------------------
            // 2) Guardar alícuota
            // -------------------------
            if (isset($_POST['SidcaiAporAlicuota'])) {
                $alicuotaData = $_POST['SidcaiAporAlicuota'];

                if (isset($alicuotaData['apor_actividad_economica']) && is_array($alicuotaData['apor_actividad_economica'])) {
                    $tmp = array_filter(array_map('trim', $alicuotaData['apor_actividad_economica']));
                    $alicuotaData['apor_actividad_economica'] = implode(',', $tmp);
                }

                $alicuotaData['es_fidetel'] = isset($alicuotaData['es_fidetel']) && $alicuotaData['es_fidetel'] ? 1 : 0;
                $alicuotaData['apor_porcprivada'] = floatval($alicuotaData['apor_porcprivada'] ?? 0);
                $alicuotaData['apor_porcpublico'] = floatval($alicuotaData['apor_porcpublico'] ?? 0);
                $alicuotaData['alicuota'] = floatval($alicuotaData['alicuota'] ?? 0);

                $crearNueva = false;
                if ($alicuotaExistente) {
                    $crearNueva = $this->alicuotaCambio($alicuotaExistente, $alicuotaData);
                } else {
                    $crearNueva = true;
                }

                if ($crearNueva) {
                    if ($alicuotaExistente) {
                        $alicuotaExistente->estatus = 3;
                        $alicuotaExistente->fecha_modificacion = new CDbExpression('NOW()');
                        if (!$alicuotaExistente->save(false)) {
                            throw new CException('Error desactivando alícuota anterior.');
                        }
                    }

                    $nueva = new SidcaiAporAlicuota();
                    $nueva->cod_aportante = $model->apor_codigo_pk;
                    foreach ($alicuotaData as $k => $v) {
                        if ($nueva->hasAttribute($k)) {
                            $nueva->$k = $v;
                        }
                    }
                    $nueva->estatus = 1;
                    $nueva->fecha_registro = new CDbExpression('NOW()');
                    $nueva->fecha_modificacion = new CDbExpression('NOW()');
                    $nueva->comentarios = 'Actualización por parte del usuario administrador';

                    if (!$nueva->save(false)) {
                        throw new CException('Error creando nueva alícuota: ' . print_r($nueva->getErrors(), true));
                    }
                } else {
                    foreach ($alicuotaData as $k => $v) {
                        if ($alicuotaExistente->hasAttribute($k)) {
                            $alicuotaExistente->$k = $v;
                        }
                    }
                    $alicuotaExistente->fecha_modificacion = new CDbExpression('NOW()');
                    if (!$alicuotaExistente->save(false)) {
                        throw new CException('Error actualizando alícuota existente: ' . print_r($alicuotaExistente->getErrors(), true));
                    }
                }
            }

            $transaction->commit();

            echo json_encode([
                'datos' => ['success', 'Aportante y alícuota guardados correctamente', 'modificar', '', 'redirigir']
            ]);
            Yii::app()->end();

        } catch (Exception $e) {
            $transaction->rollback();
            echo json_encode([
                'datos' => ['error', 'Ocurrió un error: ' . $e->getMessage(), '', '', '']
            ]);
            Yii::app()->end();
        }
    }

    // -------------------------
    // GET: Preparar datos para la vista
    // -------------------------
    Yii::import('application.controllers.FuncionesController');
    $model->apor_fechacreacionempresa = FuncionesController::convertirFecha($model->apor_fechacreacionempresa, 'dd/mm/yyyy', false);
    $model->apor_fechahoraregistro = FuncionesController::convertirFecha($model->apor_fechahoraregistro, 'dd/mm/yyyy');

    // RIF separado para mostrar
    $model->tipo_documento = substr($model->apor_rif, 0, 1);
    $model->apor_rif = substr($model->apor_rif, 1);

    // ✅ Mostrar solo el correo antes del '@' en la vista
    if (!empty($model->apor_correoelectronico) && strpos($model->apor_correoelectronico, '@') !== false) {
        $correo = explode('@', $model->apor_correoelectronico);
        $model->apor_correoelectronico = $correo[0];
    }

    $model->apor_habilitado = $model->apor_habilitado ? 1 : 0;
    $model->estatus_conciliacion = $model->estatus_conciliacion ? 1 : 0;
    $model->datos_actualizados = $model->datos_actualizados ? 1 : 0;

    $conciliaciones = SidcaiCasillasIslr::model()->with('estatusFk')->findAll([
        'condition' => 'apor_codigo_fk = :apor',
        'params' => [':apor' => $id],
    ]);

    $representantes = CHtml::listData(
        SidcaiRepresentantelegal::model()->findAll(),
        'repr_codigo_pk',
        function ($data) {
            return $data->repr_documento . ' - ' . $data->repr_nombres . ' ' . $data->repr_apellidos;
        }
    );

    $this->render('guardar', [
        'model' => $model,
        'modelAlicuota' => $modelAlicuota,
        'conciliaciones' => $conciliaciones,
        'representantes' => $representantes
    ]);
}


/**
 * Detecta si hubo cambio significativo entre la alícuota existente y los nuevos datos.
 */
private function alicuotaCambio($alicuotaExistente, $nuevosDatos) {
    $tolerancia = 0.01;

    $nuevosDatos = array_map(function($v) {
        return is_string($v) ? trim($v) : $v;
    }, $nuevosDatos);

    if ((string)$alicuotaExistente->apor_tipoempresa !== (string)($nuevosDatos['apor_tipoempresa'] ?? '')) return true;

    $existAct = array_filter(array_map('trim', explode(',', (string)$alicuotaExistente->apor_actividad_economica)));
    $newAct = array_filter(array_map('trim', explode(',', (string)($nuevosDatos['apor_actividad_economica'] ?? ''))));
    sort($existAct); sort($newAct);
    if ($existAct !== $newAct) return true;

    if ((int)$alicuotaExistente->es_fidetel !== (int)($nuevosDatos['es_fidetel'] ?? 0)) return true;

    if (abs(floatval($alicuotaExistente->apor_porcprivada) - floatval($nuevosDatos['apor_porcprivada'] ?? 0)) > $tolerancia) return true;
    if (abs(floatval($alicuotaExistente->apor_porcpublico) - floatval($nuevosDatos['apor_porcpublico'] ?? 0)) > $tolerancia) return true;
    if (abs(floatval($alicuotaExistente->alicuota) - floatval($nuevosDatos['alicuota'] ?? 0)) > $tolerancia) return true;

    return false;
}




	public function actionUpdateConciliacion()
{
    if (Yii::app()->request->isPostRequest) {
        $id = Yii::app()->request->getPost('id');
		//echo $id;die();
        $model = SidcaiCasillasIslr::model()->findByPk($id);

        if ($model) {
            //$model->apor_codigo_fk = Yii::app()->request->getPost('apor_codigo_fk');
            $model->recaudo_codigo_fk = Yii::app()->request->getPost('recaudo_codigo_fk');
           // $model->usua_codigo_fk = Yii::app()->request->getPost('usua_codigo_fk');
            //$model->motivo_rechazo_fk = Yii::app()->request->getPost('motivo_rechazo_fk');
            $model->casilla_711 = Yii::app()->request->getPost('casilla_711');
            $model->casilla_780 = Yii::app()->request->getPost('casilla_780');
            $model->casilla_970 = Yii::app()->request->getPost('casilla_970');
            $model->periodo_fiscal = Yii::app()->request->getPost('periodo_fiscal');
            $model->estatus_fk = Yii::app()->request->getPost('estatus_fk');

            if ($model->save()) {
                echo json_encode(["status" => "success"]);
            } else {
                echo json_encode(["status" => "error"]);
            }
        } else {
            echo json_encode(["status" => "not_found"]);
        }

        Yii::app()->end();
    }
}
/*
public function actionDeleteConciliacion()
{
	// Verifica si la solicitud es POST (para mayor seguridad)
	if (Yii::app()->request->isPostRequest) {
		// Obtén el ID de la conciliación desde la solicitud
		$id = Yii::app()->request->getPost('id');

		// Busca el modelo de la conciliación por su ID
		$model = SidcaiCasillasIslr::model()->findByPk($id);

		// Si el modelo existe, elimínalo
		if ($model !== null) {
			if ($model->delete()) {
				// Respuesta en caso de éxito
				echo CJSON::encode(array('success' => true, 'message' => 'Conciliación eliminada correctamente.'));
			} else {
				// Respuesta en caso de error al eliminar
				echo CJSON::encode(array('success' => false, 'message' => 'Error al eliminar la conciliación.'));
			}
		} else {
			// Respuesta si el modelo no existe
			echo CJSON::encode(array('success' => false, 'message' => 'La conciliación no existe.'));
		}
	} else {
		// Respuesta si la solicitud no es POST
		throw new CHttpException(400, 'Solicitud inválida.');
	}

	// Detén la ejecución del script después de enviar la respuesta
	Yii::app()->end();
}*/

public function actionDeleteConciliacion() {
	if(Yii::app()->request->isPostRequest) {
		$id = Yii::app()->request->getPost('id');
		$model = SidcaiCasillasIslr::model()->findByPk($id);
		
		if($model !== null) {
			if($model->delete()) {
				echo json_encode(['success' => true]);
			} else {
				echo json_encode([
					'success' => false,
					'message' => 'No se pudo eliminar la conciliación'
				]);
			}
		} else {
			echo json_encode([
				'success' => false,
				'message' => 'Conciliación no encontrada'
			]);
		}
	} else {
		throw new CHttpException(400, 'Solicitud inválida');
	}
	
	Yii::app()->end();
}

	/***	Eliminar Estatus	***/
	public function actionEliminar($id){
		try{		
			$this->loadModel($id)->delete();
			Yii::app()->user->setState('success_eliminar', 'Se ha eliminado el registro correctamente.');
		}catch(CDbException $e){
			Yii::app()->user->setState('danger_eliminar', '<b>¡Ups!</b> Ha ocurrido un error y no se pudo eliminar, intente más tarde.<br><br><b>Mensaje de error:</b><br><br>'.$e->getMessage());
		}		

		$this->redirect(Yii::app()->baseUrl. "/admin/aportante");
	}

	// Action llamado por Ajax en "dataTable.js" para mostrar todos los aportantes.
	public function actionObtenerDatosOriginal(){
		// Headers para JSON
		header('Content-Type: application/json');
		
		// Código obtenido de: https://eldesvandejose.com/2016/12/05/el-plugin-datatables-v-consumiendo-datos-externos/
		// Se adaptaron algunas partes para funcionar con el proyecto y con postgresql.
	
		$nTotal = SidcaiAportante::model()->count();
	
		// Nombre de las columnas de la BD que se mostraran en la tabla
		$columnasParaRetorno = [
			'apor_codigo_pk', 
			'apor_rif',
			'apor_razonsocial', 
			'apor_denominacion',
			'apor_direccion',
			'datos_actualizados',
			'acciones'
		];
	
		$datosDeLlamada = $_GET;
	
		/* PREPARAMOS EL FILTRADO POR COLUMNAS PARA LA CAJA DE BUSQUEDA */
	
		$consulta = "";
	
		if (isset($datosDeLlamada['sSearch']) && $datosDeLlamada['sSearch'] !== "") {
			for($i = 0; $i < count($columnasParaRetorno); $i++) {
				if (isset ($datosDeLlamada['bSearchable_'.$i]) && $datosDeLlamada['bSearchable_'.$i] == 'true') {
					if($i == (count($columnasParaRetorno) -1)){
						$or = "";
					}else{
						$or = " OR ";
					}
	
					// If que se coloca para evitar problemas con la columna "Acciones".
					if($columnasParaRetorno[$i] == "acciones")
						$columnasParaRetorno[$i] = "apor_codigo_pk";
	
					$consulta .= " CAST(".$columnasParaRetorno[$i]." AS text) LIKE '%".addslashes($datosDeLlamada['sSearch'])."%'".$or;
				}
			}
	
			$consulta = "WHERE " .$consulta;
		}
	
		// Regla de ordenación
		$ordenado = "";
	
		if (isset($datosDeLlamada['iSortCol_0'] )) {
			$columnasDeOrdenacion = intval($datosDeLlamada['iSortingCols']);
			for($i = 0; $i < $columnasDeOrdenacion; $i ++) {
				if ($datosDeLlamada['bSortable_'.intval($datosDeLlamada['iSortCol_'.$i])] == 'true') {
					if($columnasParaRetorno[intval($datosDeLlamada['iSortCol_'.$i])] == "acciones")
						$columnasParaRetorno[intval($datosDeLlamada['iSortCol_'.$i])] = "apor_codigo_pk";
	
					$ordenado = $columnasParaRetorno[intval($datosDeLlamada['iSortCol_'.$i])].($datosDeLlamada['sSortDir_'.$i] === 'asc'?' asc':' desc'); 
					break;
				}
			}
	
			$ordenado = "ORDER BY " .$ordenado;
		}
	
		$offset = $datosDeLlamada['iDisplayStart'];
		$limit  = $datosDeLlamada['iDisplayLength'];
	
		$totalFiltro = 0;
	
		$connection = Yii::app()->db;
		// Obtiene los registros.
		$sql = "SELECT apor_codigo_pk, apor_razonsocial, apor_denominacion, apor_rif, apor_direccion, datos_actualizados FROM sidcai_aportante $consulta $ordenado OFFSET $offset LIMIT $limit";
		$command = $connection->createCommand();
		$command->text = $sql;
		$model = $command->queryAll();
	
		// Obtiene el numero de registro filtrados
		$sql = "SELECT COUNT(*) FROM sidcai_aportante $consulta";
		$command = $connection->createCommand();
		$command->text = $sql;
		$totalFiltro = $command->queryAll();
		$totalFiltro = $totalFiltro[0]['count'];
	
		$aaData = [];
	
		foreach($model as $m){
			$ver = '<a class="btn-acciones text-info p-2" title="Ver" href="'.Yii::app()->homeUrl.'admin/aportante/' .$m['apor_codigo_pk']. '"><i class="far fa-eye"></i></a>';
			$modificar = '<a class="btn-acciones text-warning p-2" title="Modificar" href="'.Yii::app()->homeUrl.'admin/aportante/modificar/' .$m['apor_codigo_pk']. '"><i class="fas fa-pen"></i></a>';
			$borrar = '<a class="btn-acciones text-danger p-2" title="Eliminar" href="" data-toggle="modal" data-target=".bd-example-modal-sm" onclick="eliminar(' .$m['apor_codigo_pk']. ')"><i class="fas fa-times"></i></a>';
	
			// Badge para datos actualizados
			if ($m['datos_actualizados'] == true || $m['datos_actualizados'] === 't' || $m['datos_actualizados'] == 1) {
				$badge = '<span class="badge badge-success">Actualizado</span>';
			} else {
				$badge = '<span class="badge badge-secondary">No actualizado</span>';
			}
	
			$aaData[] = [
				$m['apor_codigo_pk'],
				$m['apor_rif'],
				$m['apor_razonsocial'],
				$m['apor_denominacion'],
				$m['apor_direccion'],
				$badge,
				$ver.$modificar.$borrar
			];
		}
	
		$aData = [
			'sEcho' => intval($datosDeLlamada['sEcho']),
			'iTotalRecords' => strval($nTotal),
			'iTotalDisplayRecords' => strval($totalFiltro),
			'aaData' => $aaData
		];
	
		// Verificar integridad del JSON
		$json = json_encode($aData);
		if ($json === false) {
			$error = json_last_error_msg();
			echo json_encode(['error' => 'JSON encoding failed: ' . $error]);
		} else {
			echo $json;
		}
		
		Yii::app()->end();
	}


public function actionObtenerDatos1011(){
    header('Content-Type: application/json');
    
    try {
        $connection = Yii::app()->db;
        $datosDeLlamada = $_GET;
        $condiciones = [];
        $params = [];

        // Filtro global (DataTable)
        if (!empty($datosDeLlamada['search']['value'])) {
            $search = trim($datosDeLlamada['search']['value']);
            $search = str_replace("'", "''", $search);
            $condiciones[] = "(apor_rif ILIKE :search OR apor_razonsocial ILIKE :search OR apor_denominacion ILIKE :search OR apor_direccion ILIKE :search)";
            $params[':search'] = "%$search%";
        }

        // 🔽 Filtros personalizados
        if (!empty($datosDeLlamada['estado'])) {
            $condiciones[] = "esta_codigo_fk = :estado";
            $params[':estado'] = $datosDeLlamada['estado'];
        }
        
        if (!empty($datosDeLlamada['estatus'])) {
            $condiciones[] = "esta_codigoestatus_fk = :estatus";
            $params[':estatus'] = $datosDeLlamada['estatus'];
        }
        
        if (isset($datosDeLlamada['actualizado']) && $datosDeLlamada['actualizado'] !== '') {
            if ($datosDeLlamada['actualizado'] === '1') {
                $condiciones[] = "datos_actualizados = TRUE";
            } else {
                $condiciones[] = "(datos_actualizados IS FALSE OR datos_actualizados IS NULL)";
            }
        }
        
        if (!empty($datosDeLlamada['fecha'])) {
            $condiciones[] = "DATE(fecha_registro) = :fecha";
            $params[':fecha'] = $datosDeLlamada['fecha'];
        }

        $where = !empty($condiciones) ? "WHERE " . implode(" AND ", $condiciones) : "";

        // Conteo total
        $nTotal = $connection->createCommand("SELECT COUNT(*) FROM sidcai_aportante")->queryScalar();

        // Conteo filtrado
        $sqlCount = "SELECT COUNT(*) FROM sidcai_aportante $where";
        $totalFiltro = $connection->createCommand($sqlCount)->queryScalar($params);

        // Ordenamiento
        $order = "ORDER BY apor_codigo_pk DESC";
        if (!empty($datosDeLlamada['order'][0])) {
            $columnIndex = intval($datosDeLlamada['order'][0]['column']);
            $columnDirection = $datosDeLlamada['order'][0]['dir'];
            $columns = ['apor_codigo_pk', 'apor_rif', 'apor_razonsocial', 'apor_denominacion', 'apor_direccion', 'datos_actualizados'];
            
            if (isset($columns[$columnIndex])) {
                $order = "ORDER BY " . $columns[$columnIndex] . " " . ($columnDirection === 'asc' ? 'ASC' : 'DESC');
            }
        }

        // Paginación
        $offset = isset($datosDeLlamada['start']) ? intval($datosDeLlamada['start']) : 0;
        $limit = isset($datosDeLlamada['length']) ? intval($datosDeLlamada['length']) : 10;

        // Consulta principal
        $sql = "SELECT 
                    apor_codigo_pk, 
                    apor_rif, 
                    apor_razonsocial, 
                    apor_denominacion, 
                    apor_direccion, 
                    datos_actualizados,
                    apor_correoelectronico
                FROM sidcai_aportante 
                $where 
                $order 
                LIMIT $limit OFFSET $offset";
                
        $model = $connection->createCommand($sql)->queryAll(true, $params);

        $aaData = [];
        foreach ($model as $m) {
            $ver = '<a class="btn-acciones text-info p-2" title="Ver" href="' . Yii::app()->homeUrl . 'admin/aportante/' . $m['apor_codigo_pk'] . '"><i class="far fa-eye"></i></a>';
            $modificar = '<a class="btn-acciones text-warning p-2" title="Modificar" href="' . Yii::app()->homeUrl . 'admin/aportante/modificar/' . $m['apor_codigo_pk'] . '"><i class="fas fa-pen"></i></a>';
            $borrar = '<a class="btn-acciones text-danger p-2" title="Eliminar" href="" data-toggle="modal" data-target=".bd-example-modal-sm" onclick="eliminar(' . $m['apor_codigo_pk'] . ')"><i class="fas fa-times"></i></a>';
            
            // 🔽 Botón de correo individual (solo para no actualizados)
            $correoBtn = '';
            if (!$m['datos_actualizados'] && !empty($m['apor_correoelectronico'])) {
                $correoBtn = '<a class="btn-acciones text-success p-2 enviarCorreoIndividual" title="Enviar correo" href="#"
                               data-id="' . $m['apor_codigo_pk'] . '"
                               data-correo="' . $m['apor_correoelectronico'] . '"
                               data-nombre="' . htmlspecialchars($m['apor_razonsocial']) . '">
                              <i class="fas fa-envelope"></i></a>';
            }

            $badge = ($m['datos_actualizados']) 
                ? '<span class="badge bg-success">Sí</span>' 
                : '<span class="badge bg-warning">No</span>';

            $aaData[] = [
                $m['apor_codigo_pk'],
                $m['apor_rif'],
                $m['apor_razonsocial'],
                $m['apor_denominacion'],
                $m['apor_direccion'],
                $badge,
                $ver.$modificar.$borrar.$correoBtn
            ];
        }

        // ✅ CORRECCIÓN: Usar 'draw' en lugar de 'sEcho'
        $response = [
            'draw' => isset($datosDeLlamada['draw']) ? intval($datosDeLlamada['draw']) : 0,
            'recordsTotal' => intval($nTotal),
            'recordsFiltered' => intval($totalFiltro),
            'data' => $aaData
        ];
        
        echo json_encode($response);
        
    } catch (Exception $e) {
        // En caso de error, devolver una respuesta válida para DataTables
        $response = [
            'draw' => isset($datosDeLlamada['draw']) ? intval($datosDeLlamada['draw']) : 0,
            'recordsTotal' => 0,
            'recordsFiltered' => 0,
            'data' => [],
            'error' => $e->getMessage()
        ];
        echo json_encode($response);
    }
    
    Yii::app()->end();
}

public function actionObtenerDatos() {
    header('Content-Type: application/json');

    try {
        $connection = Yii::app()->db;
        $datosDeLlamada = $_GET;
        $condiciones = [];
        $params = [];

        // Filtro global (DataTable)
        if (!empty($datosDeLlamada['search']['value'])) {
            $search = trim($datosDeLlamada['search']['value']);
            $search = str_replace("'", "''", $search);
            $condiciones[] = "(apor_rif ILIKE :search OR apor_razonsocial ILIKE :search OR apor_denominacion ILIKE :search OR apor_direccion ILIKE :search)";
            $params[':search'] = "%$search%";
        }

        // Filtros personalizados
        if (!empty($datosDeLlamada['estado'])) {
            $condiciones[] = "esta_codigo_fk = :estado";
            $params[':estado'] = $datosDeLlamada['estado'];
        }

        if (!empty($datosDeLlamada['estatus'])) {
            $condiciones[] = "esta_codigoestatus_fk = :estatus";
            $params[':estatus'] = $datosDeLlamada['estatus'];
        }

        if (isset($datosDeLlamada['actualizado']) && $datosDeLlamada['actualizado'] !== '') {
            if ($datosDeLlamada['actualizado'] === '1') {
                $condiciones[] = "datos_actualizados = TRUE";
            } else {
                $condiciones[] = "(datos_actualizados IS FALSE OR datos_actualizados IS NULL)";
            }
        }

        if (!empty($datosDeLlamada['fecha'])) {
            $condiciones[] = "DATE(apor_fechahoraregistro) = :fecha";
            $params[':fecha'] = $datosDeLlamada['fecha'];
        }

        $where = !empty($condiciones) ? "WHERE " . implode(" AND ", $condiciones) : "";

        // Conteo total
        $nTotal = $connection->createCommand("SELECT COUNT(*) FROM sidcai_aportante")->queryScalar();

        // Conteo filtrado
        $sqlCount = "SELECT COUNT(*) FROM sidcai_aportante $where";
        $totalFiltro = $connection->createCommand($sqlCount)->queryScalar($params);

        // Ordenamiento
        $order = "ORDER BY apor_codigo_pk DESC";
        if (!empty($datosDeLlamada['order'][0])) {
            $columnIndex = intval($datosDeLlamada['order'][0]['column']);
            $columnDirection = $datosDeLlamada['order'][0]['dir'];
            $columns = ['apor_codigo_pk', 'apor_rif', 'apor_razonsocial', 'apor_denominacion', 'apor_direccion', 'datos_actualizados'];

            if (isset($columns[$columnIndex])) {
                $order = "ORDER BY " . $columns[$columnIndex] . " " . ($columnDirection === 'asc' ? 'ASC' : 'DESC');
            }
        }

        // Paginación
        $offset = isset($datosDeLlamada['start']) ? intval($datosDeLlamada['start']) : 0;
        $limit = isset($datosDeLlamada['length']) ? intval($datosDeLlamada['length']) : 10;

        // Consulta principal
        $sql = "SELECT 
                    apor_codigo_pk, 
                    apor_rif, 
                    apor_razonsocial, 
                    apor_denominacion, 
                    apor_direccion, 
                    apor_correoelectronico,
                    esta_codigoestatus_fk,
                    datos_actualizados
                FROM sidcai_aportante 
                $where 
                $order 
                LIMIT $limit OFFSET $offset";

        $model = $connection->createCommand($sql)->queryAll(true, $params);

        $aaData = [];
        foreach ($model as $m) {
            $ver = '<a class="btn-acciones text-info p-2" title="Ver" href="' . Yii::app()->homeUrl . 'admin/aportante/' . $m['apor_codigo_pk'] . '"><i class="far fa-eye"></i></a>';
            $modificar = '<a class="btn-acciones text-warning p-2" title="Modificar" href="' . Yii::app()->homeUrl . 'admin/aportante/modificar/' . $m['apor_codigo_pk'] . '"><i class="fas fa-pen"></i></a>';
            $borrar = '<a class="btn-acciones text-danger p-2" title="Eliminar" href="" data-toggle="modal" data-target=".bd-example-modal-sm" onclick="eliminar(' . $m['apor_codigo_pk'] . ')"><i class="fas fa-times"></i></a>';

            // Botón correo (solo si no está actualizado)
            $correoBtn = '';
            if (!$m['datos_actualizados'] && !empty($m['apor_correoelectronico'])) {
                $correoBtn = '<a class="btn-acciones text-success p-2 enviarCorreoIndividual" title="Enviar correo"
                               href="#" data-id="' . $m['apor_codigo_pk'] . '"
                               data-correo="' . $m['apor_correoelectronico'] . '"
                               data-nombre="' . htmlspecialchars($m['apor_razonsocial']) . '">
                               <i class="fas fa-envelope"></i></a>';
            }

            // Badge actualizado
            $badge = ($m['datos_actualizados'])
                ? '<span class="badge bg-success">Sí</span>'
                : '<span class="badge bg-warning">No</span>';

            // ✅ Si estatus es 2009 y tiene registros en historial → mostrar botón de historial
            $historialBtn = '';
            if ($m['esta_codigoestatus_fk'] == 2009) {
                $countHistorial = $connection->createCommand("
                    SELECT COUNT(*) FROM sidcai_historia_historial WHERE apor_codigo_fk = :apor
                ")->queryScalar([':apor' => $m['apor_codigo_pk']]);

                if ($countHistorial > 0) {
                    $historialBtn = '<a class="btn-acciones text-primary p-2 verHistorial" 
                        href="#" data-id="' . $m['apor_codigo_pk'] . '" 
                        title="Ver historial">
                        <i class="fas fa-clock"></i></a>';
                }
            }

            $aaData[] = [
                $m['apor_codigo_pk'],
                $m['apor_rif'],
                $m['apor_razonsocial'],
                $m['apor_denominacion'],
                $m['apor_direccion'],
                $badge,
                $ver . $modificar . $borrar . $correoBtn . $historialBtn
            ];
        }

        $response = [
            'draw' => isset($datosDeLlamada['draw']) ? intval($datosDeLlamada['draw']) : 0,
            'recordsTotal' => intval($nTotal),
            'recordsFiltered' => intval($totalFiltro),
            'data' => $aaData
        ];

        echo json_encode($response);
    } catch (Exception $e) {
        echo json_encode([
            'draw' => isset($datosDeLlamada['draw']) ? intval($datosDeLlamada['draw']) : 0,
            'recordsTotal' => 0,
            'recordsFiltered' => 0,
            'data' => [],
            'error' => $e->getMessage()
        ]);
    }

    Yii::app()->end();
}

public function actionVerHistorial1011($id) {
    $connection = Yii::app()->db;
    $historial = $connection->createCommand("
        SELECT archivo, fecha_creacion, observaciones
        FROM sidcai_historia_historial
        WHERE apor_codigo_fk = :id
        ORDER BY fecha_creacion DESC
    ")->queryAll(true, [':id' => $id]);

    $html = "<table class='table table-sm table-striped'>
        <thead><tr><th>Archivo</th><th>Fecha</th><th>Observación</th></tr></thead><tbody>";

    foreach ($historial as $h) {
        $html .= "<tr>
            <td><a href='" . Yii::app()->baseUrl . "/upload/historial/" . htmlspecialchars($h['archivo']) . "' target='_blank'>Ver archivo</a></td>
            <td>" . date('d/m/Y H:i', strtotime($h['fecha_creacion'])) . "</td>
            <td>" . htmlspecialchars($h['observaciones']) . "</td>
        </tr>";
    }

    $html .= "</tbody></table>";

    echo $html;
    Yii::app()->end();
}



public function actionVerHistorial($id)
{
    $connection = Yii::app()->db;
    $historial = $connection->createCommand("
        SELECT archivo, fecha_creacion, observaciones
        FROM sidcai_historia_historial
        WHERE apor_codigo_fk = :id
        ORDER BY fecha_creacion DESC
    ")->queryAll(true, [':id' => $id]);

    $html = "<table class='table table-sm table-striped'>
        <thead>
            <tr>
                <th>Archivo</th>
                <th>Fecha</th>
                <th>Observación</th>
            </tr>
        </thead>
        <tbody>";

    foreach ($historial as $h) {
        $archivo = $h['archivo'];
        $apor_codigo_fk = $id;

        // 🔹 Ruta local
        $rutaLocal = Yii::getPathOfAlias('webroot') . "/upload/{$apor_codigo_fk}/estatus2009/" . $archivo;

        // 🔹 Ruta SSH (misma estructura que usas en tu función)
        $remoteBaseDir = '/ruta/remota/'; // <-- ajusta esto según tu servidor
        $rutaSSH = $remoteBaseDir . $apor_codigo_fk . '/estatus2009/' . $archivo;

        // 🔍 Verificar existencia
        $estado = FuncionesController::actionCheckFileExistence($rutaLocal);

        if ($estado == 0) {
            // Si no está local, probamos remoto
            $estado = FuncionesController::actionCheckFileExistence($rutaSSH);
        }

        // 🔗 Generar enlace según el origen
        if ($estado == 1) {
            // Local
            $link = CHtml::link(
                '<i class="fa fa-download"></i> Descargar Local',
                array('funciones/download', 'archivo' => $archivo, 'apor' => $apor_codigo_fk, 'modo' => 'local'),
                array('class' => 'btn btn-success btn-sm', 'target' => '_blank')
            );
        } elseif ($estado == 2) {
            // SSH
            $link = CHtml::link(
                '<i class="fa fa-cloud-download-alt"></i> Descargar SSH',
                array('funciones/download', 'archivo' => $archivo, 'apor' => $apor_codigo_fk, 'modo' => 'ssh'),
                array('class' => 'btn btn-info btn-sm', 'target' => '_blank')
            );
        } else {
            // No disponible
            $link = "<span class='badge bg-danger'>Archivo no disponible</span>";
        }

        $html .= "<tr>
            <td>$link</td>
            <td>" . date('d/m/Y H:i', strtotime($h['fecha_creacion'])) . "</td>
            <td>" . htmlspecialchars($h['observaciones']) . "</td>
        </tr>";
    }

    $html .= "</tbody></table>";

    echo $html;
    Yii::app()->end();
}



public static function actionCheckFileExistence($ruta)
{
    // Verificar si existe localmente
    if (file_exists($ruta)) {
        return 1;
    }

    // Si no existe local, verificar SSH
    $connection = @ssh2_connect('tuservidor.com', 22);
    if ($connection && @ssh2_auth_password($connection, 'usuario', 'clave')) {
        $sftp = @ssh2_sftp($connection);
        if (file_exists("ssh2.sftp://{$sftp}{$ruta}")) {
            return 2;
        }
    }

    return 0; // No existe
}


public function actionDownload()
{
    $id = $_GET['id'] ?? null;

    if (!$id) {
        throw new CHttpException(400, 'Parámetro ID no especificado.');
    }

    // Buscar el recaudo
    $recaudo = SidcaiRecaudo::model()->findByPk($id);

    if (!$recaudo) {
        Yii::app()->user->setFlash('error', 'No se encontró el recaudo solicitado.');
        $this->redirect(['index']);
        return;
    }

    $archivo = $recaudo->reca_direccion;

    if (empty($archivo)) {
        Yii::app()->user->setFlash('error', 'Este recaudo debe ser cargado nuevamente por el aportante.');
        $this->redirect(['index']);
        return;
    }

    // ✅ Verificar si el archivo existe localmente
    $rutaLocal = Yii::getPathOfAlias('webroot') . '/' . ltrim($archivo, '/');
    $existeLocal = file_exists($rutaLocal);

    if ($existeLocal) {
        // 🔹 Descargar desde servidor local
        return Yii::app()->getRequest()->sendFile(basename($rutaLocal), file_get_contents($rutaLocal));
    } else {
        // 🔹 Si no está local, intentar por SSH
        $archivoRemoto = FuncionesController::actionCheckFileExistence($archivo);

        if ($archivoRemoto == 0) {
            Yii::app()->user->setFlash('error', 'El archivo no se encuentra disponible ni local ni remoto.');
            $this->redirect(['index']);
            return;
        }

        // 🔹 Descargar remotamente por SFTP
        return FuncionesController::DescargarFile($archivo);
    }
}




public function actionEnviarCorreosNoActualizados()
{
    header('Content-Type: application/json');
    
    try {
        $request = Yii::app()->request;
        $filtros = ["(datos_actualizados IS FALSE OR datos_actualizados IS NULL)"];
        $params  = [];

        // Filtrar por estado
        if (!empty($request->getPost('estado'))) {
            $filtros[] = "esta_codigo_fk = :estado";
            $params[':estado'] = $request->getPost('estado');
        }

        // Filtrar por estatus
        if (!empty($request->getPost('estatus'))) {
            $filtros[] = "esta_codigoestatus_fk = :estatus";
            $params[':estatus'] = $request->getPost('estatus');
        }

        // Filtrar por fecha
        if (!empty($request->getPost('fecha'))) {
            $filtros[] = "DATE(fecha_registro) = :fecha";
            $params[':fecha'] = $request->getPost('fecha');
        }

        // Filtrar por actualizado (si se especifica)
        if (!empty($request->getPost('actualizado'))) {
            if ($request->getPost('actualizado') === '1') {
                $filtros[] = "datos_actualizados = TRUE";
            } else {
                $filtros[] = "(datos_actualizados IS FALSE OR datos_actualizados IS NULL)";
            }
        }

        $where = !empty($filtros) ? "WHERE " . implode(" AND ", $filtros) : "";

        // Consulta mejorada para incluir solo aportantes con correo válido
        $aportantes = Yii::app()->db->createCommand("
            SELECT 
                apor_codigo_pk, 
                apor_rif, 
                apor_razonsocial, 
                apor_correoelectronico,
                apor_denominacion
            FROM sidcai_aportante
            $where
            AND apor_correoelectronico IS NOT NULL 
            AND apor_correoelectronico != ''
            AND TRIM(apor_correoelectronico) != ''
        ")->bindValues($params)->queryAll();

        if (empty($aportantes)) {
            echo json_encode([
                'success' => true,
                'mensaje' => 'No se encontraron aportantes que cumplan con los criterios especificados.',
                'enviados' => 0,
                'total' => 0
            ]);
            Yii::app()->end();
        }

        $enviados = 0;
        $errores = [];
        $total = count($aportantes);

        foreach ($aportantes as $a) {
            $correo = trim($a['apor_correoelectronico']);
            
            // Validar formato de email
            if (!filter_var($correo, FILTER_VALIDATE_EMAIL)) {
                $errores[] = "Email inválido: {$correo} - {$a['apor_razonsocial']}";
                continue;
            }

            // Mensaje más profesional y personalizado
            $nombre = !empty($a['apor_denominacion']) ? $a['apor_denominacion'] : $a['apor_razonsocial'];
            $titulo = "Solicitud de Actualización de Datos - " . date('d/m/Y');
            
            $mensaje = "
Estimado(a) {$nombre},

Le informamos que es necesario actualizar sus datos en nuestro sistema para mantener la información actualizada y garantizar una comunicación efectiva.

RIF: {$a['apor_rif']}
Razón Social: {$a['apor_razonsocial']}

Por favor, acceda a nuestro sistema y complete la actualización de la siguiente información:
- Datos de contacto
- Información fiscal
- Dirección actualizada
- Representantes legales

Si ya ha actualizado sus datos recientemente, por favor ignore este mensaje.

Agradecemos su pronta atención a este importante requerimiento.

Saludos cordiales,
Departamento de Administración
            ";

            try {
                // CORRECCIÓN DEFINITIVA: Pasar como arrays [$correo] y [$nombre]
                if (FuncionesController::enviarCorreo([$correo], [$nombre], $titulo, trim($mensaje))) {
                    $enviados++;
                    
                    // Opcional: Registrar en log
                    Yii::log("Correo enviado a: {$correo} - {$a['apor_razonsocial']}", 'info', 'application');
                    
                } else {
                    $errores[] = "Error al enviar a: {$correo} - {$a['apor_razonsocial']}";
                }
                
            } catch (Exception $e) {
                $errores[] = "Excepción con {$correo}: " . $e->getMessage();
            }
            
            // Pequeña pausa para no saturar el servidor de correo
            usleep(100000); // 0.1 segundos
        }

        // Preparar respuesta
        $respuesta = [
            'success' => true,
            'mensaje' => "Proceso completado. Correos enviados: {$enviados} de {$total} aportantes.",
            'enviados' => $enviados,
            'total' => $total,
            'errores' => $errores
        ];

        // Si hay muchos errores, considerar como fallo parcial
        if (count($errores) > ($total * 0.5)) { // Más del 50% de errores
            $respuesta['success'] = false;
            $respuesta['mensaje'] = "Se produjeron muchos errores al enviar los correos.";
        }

        echo json_encode($respuesta);

    } catch (Exception $e) {
        // Manejo de errores generales
        echo json_encode([
            'success' => false,
            'mensaje' => 'Error en el proceso de envío de correos: ' . $e->getMessage(),
            'enviados' => 0,
            'total' => 0,
            'errores' => [$e->getMessage()]
        ]);
    }
    
    Yii::app()->end();
}


public function actionEnviarCorreoIndividual()
{
    header('Content-Type: application/json');
    
    try {
        $request = Yii::app()->request;
        
        $id = $request->getPost('id');
        $correo = $request->getPost('correo');
        $asunto = $request->getPost('asunto', 'Solicitud de Actualización de Datos');
        $mensaje = $request->getPost('mensaje');
        
        // Validaciones
        if (empty($id) || empty($correo)) {
            throw new Exception('Datos incompletos para enviar el correo.');
        }
        
        if (!filter_var($correo, FILTER_VALIDATE_EMAIL)) {
            throw new Exception('Dirección de correo electrónico inválida.');
        }
        
        // Obtener información del aportante
        $aportante = Yii::app()->db->createCommand()
            ->select('apor_razonsocial, apor_denominacion, apor_rif')
            ->from('sidcai_aportante')
            ->where('apor_codigo_pk = :id', [':id' => $id])
            ->queryRow();
            
        if (!$aportante) {
            throw new Exception('Aportante no encontrado.');
        }
        
        $nombre = !empty($aportante['apor_denominacion']) ? $aportante['apor_denominacion'] : $aportante['apor_razonsocial'];
        
        // Personalizar mensaje si contiene {nombre}
        $mensajePersonalizado = str_replace('{nombre}', $nombre, $mensaje);
        
        // CORRECCIÓN DEFINITIVA: Pasar como arrays [$correo] y [$nombre]
        $enviado = FuncionesController::enviarCorreo([$correo], [$nombre], $asunto, $mensajePersonalizado);
        
        if ($enviado) {
            // Registrar en log
            Yii::log("Correo individual enviado a: {$correo} - {$nombre}", 'info', 'application');
            
            echo json_encode([
                'success' => true,
                'mensaje' => 'Correo enviado correctamente.',
                'destinatario' => $correo
            ]);
        } else {
            throw new Exception('No se pudo enviar el correo. Verifique la configuración del servidor de correo.');
        }
        
    } catch (Exception $e) {
        echo json_encode([
            'success' => false,
            'mensaje' => $e->getMessage()
        ]);
    }
    
    Yii::app()->end();
}


public function actionEnviarCorreosNoActualizadosultima()
{
    $request = Yii::app()->request;
    $filtros = ["(datos_actualizados IS FALSE OR datos_actualizados IS NULL)"];
    $params  = [];

    // Filtrar por estado
    if (!empty($request->getPost('estado'))) {
        $filtros[] = "esta_codigo_fk = :estado";
        $params[':estado'] = $request->getPost('estado');
    }

    // Filtrar por estatus
    if (!empty($request->getPost('estatus'))) {
        $filtros[] = "esta_codigoestatus_fk = :estatus";
        $params[':estatus'] = $request->getPost('estatus');
    }

    // Filtrar por fecha
    if (!empty($request->getPost('fecha'))) {
        $filtros[] = "DATE(fecha_registro) = :fecha";
        $params[':fecha'] = $request->getPost('fecha');
    }

    $where = !empty($filtros) ? "WHERE " . implode(" AND ", $filtros) : "";

    $aportantes = Yii::app()->db->createCommand("
        SELECT apor_codigo_pk, apor_rif, apor_razonsocial, apor_correo
        FROM sidcai_aportante
        $where
    ")->bindValues($params)->queryAll();

    $enviados = 0;
    foreach ($aportantes as $a) {
        $mensaje = "Estimado(a) {$a['apor_razonsocial']}, por favor actualice sus datos.";
        if (FuncionesController::enviarCorreo($a['apor_correo'], "Actualiza tus datos", $mensaje)) {
            $enviados++;
        }
    }

    echo json_encode(['mensaje' => "Correos enviados a $enviados aportantes."]);
    Yii::app()->end();
}




	public function actionObtenerDatos0511ultima()
{
    header('Content-Type: application/json');

    $connection = Yii::app()->db;
    $datosDeLlamada = $_GET;

    // Campos que se mostrarán en la tabla
    $columnasParaRetorno = [
        'apor_codigo_pk',
        'apor_rif',
        'apor_razonsocial',
        'apor_denominacion',
        'apor_direccion',
        'datos_actualizados',
        'acciones'
    ];

    // 🔍 Búsqueda global optimizada
    $consulta = "";
    $params = [];

    if (!empty($datosDeLlamada['sSearch'])) {
        $search = trim($datosDeLlamada['sSearch']);
        $condiciones = [];
        foreach (['apor_rif', 'apor_razonsocial', 'apor_denominacion', 'apor_direccion'] as $columna) {
            $condiciones[] = "$columna ILIKE :search";
        }
        $consulta = "WHERE (" . implode(" OR ", $condiciones) . ")";
        $params[':search'] = "%$search%";
    }

    // 🧭 Orden
    $ordenado = "";
    if (!empty($datosDeLlamada['iSortCol_0'])) {
        $columnaOrden = $columnasParaRetorno[intval($datosDeLlamada['iSortCol_0'])];
        if ($columnaOrden == 'acciones') {
            $columnaOrden = 'apor_codigo_pk';
        }
        $dir = ($datosDeLlamada['sSortDir_0'] === 'asc') ? 'ASC' : 'DESC';
        $ordenado = "ORDER BY $columnaOrden $dir";
    } else {
        $ordenado = "ORDER BY apor_codigo_pk DESC";
    }

    // 📄 Paginación
    $offset = isset($datosDeLlamada['iDisplayStart']) ? intval($datosDeLlamada['iDisplayStart']) : 0;
    $limit  = isset($datosDeLlamada['iDisplayLength']) ? intval($datosDeLlamada['iDisplayLength']) : 10;

    // 🔢 Total general y filtrado
    $sqlCount = "SELECT COUNT(*) AS total FROM sidcai_aportante";
    $sqlCountFiltro = "SELECT COUNT(*) AS total FROM sidcai_aportante $consulta";

    $totalGeneral = $connection->createCommand($sqlCount)->queryScalar();
    $command = $connection->createCommand($sqlCountFiltro);
    $command->bindValues($params);
    $totalFiltro = $command->queryScalar();

    // ⚡ Consulta principal optimizada
    $sql = "SELECT apor_codigo_pk, apor_razonsocial, apor_denominacion, apor_rif, apor_direccion, datos_actualizados
            FROM sidcai_aportante
            $consulta
            $ordenado
            LIMIT $limit OFFSET $offset";
    $command = $connection->createCommand($sql);
    $command->bindValues($params);
    $model = $command->queryAll();

    // 📬 Preparar resultados
    $aaData = [];
    foreach ($model as $m) {
        $ver = '<a class="btn-acciones text-info p-2" title="Ver" href="' . Yii::app()->homeUrl . 'admin/aportante/' . $m['apor_codigo_pk'] . '"><i class="far fa-eye"></i></a>';
        $modificar = '<a class="btn-acciones text-warning p-2" title="Modificar" href="' . Yii::app()->homeUrl . 'admin/aportante/modificar/' . $m['apor_codigo_pk'] . '"><i class="fas fa-pen"></i></a>';
        $borrar = '<a class="btn-acciones text-danger p-2" title="Eliminar" href="#" onclick="eliminar(' . $m['apor_codigo_pk'] . ')"><i class="fas fa-times"></i></a>';

        if ($m['datos_actualizados'] == true || $m['datos_actualizados'] === 't' || $m['datos_actualizados'] == 1) {
            $badge = '<span class="badge badge-success">Actualizado</span>';
        } else {
            // 📧 Agrega botón para enviar correo a los no actualizados
            $badge = '<button class="btn btn-sm btn-danger" onclick="enviarCorreoIndividual(' . $m['apor_codigo_pk'] . ')">Enviar correo</button>';
        }

        $aaData[] = [
            $m['apor_codigo_pk'],
            $m['apor_rif'],
            $m['apor_razonsocial'],
            $m['apor_denominacion'],
            $m['apor_direccion'],
            $badge,
            $ver . $modificar . $borrar
        ];
    }

    // 📊 Enviar JSON al DataTable
    echo json_encode([
        'sEcho' => intval($datosDeLlamada['sEcho']),
        'iTotalRecords' => intval($totalGeneral),
        'iTotalDisplayRecords' => intval($totalFiltro),
        'aaData' => $aaData
    ]);
    Yii::app()->end();
}


	public function actionObtenerDatos05112025(){
		// Headers para JSON
		header('Content-Type: application/json');
		
		$nTotal = SidcaiAportante::model()->count();
	
		// Nombre de las columnas de la BD que se mostraran en la tabla
		$columnasParaRetorno = [
			'apor_codigo_pk', 
			'apor_rif',
			'apor_razonsocial', 
			'apor_denominacion',
			'apor_direccion',
			'datos_actualizados',
			'acciones'
		];
	
		$datosDeLlamada = $_GET;
	
		/* PREPARAMOS EL FILTRADO POR COLUMNAS PARA LA CAJA DE BUSQUEDA */
	
		$consulta = "";
	
		if (isset($datosDeLlamada['sSearch']) && $datosDeLlamada['sSearch'] !== "") {
			$condiciones = [];
			
			for($i = 0; $i < count($columnasParaRetorno); $i++) {
				if (isset ($datosDeLlamada['bSearchable_'.$i]) && $datosDeLlamada['bSearchable_'.$i] == 'true') {
					
					$columna = $columnasParaRetorno[$i];
					
					// If que se coloca para evitar problemas con la columna "Acciones".
					if($columna == "acciones") {
						$columna = "apor_codigo_pk";
					}
					
					$condiciones[] = " CAST(".$columna." AS text) LIKE '%".addslashes($datosDeLlamada['sSearch'])."%'";
				}
			}
			
			if (!empty($condiciones)) {
				$consulta = "WHERE " . implode(" OR ", $condiciones);
			}
		}
	
		// Regla de ordenación
		$ordenado = "";
	
		if (isset($datosDeLlamada['iSortCol_0'] )) {
			$columnasDeOrdenacion = intval($datosDeLlamada['iSortingCols']);
			for($i = 0; $i < $columnasDeOrdenacion; $i ++) {
				if ($datosDeLlamada['bSortable_'.intval($datosDeLlamada['iSortCol_'.$i])] == 'true') {
					$columnaOrden = $columnasParaRetorno[intval($datosDeLlamada['iSortCol_'.$i])];
					if($columnaOrden == "acciones") {
						$columnaOrden = "apor_codigo_pk";
					}
	
					$ordenado = $columnaOrden . ($datosDeLlamada['sSortDir_'.$i] === 'asc'?' asc':' desc'); 
					break;
				}
			}
	
			$ordenado = "ORDER BY " . $ordenado;
		}
	
		$offset = $datosDeLlamada['iDisplayStart'];
		$limit  = $datosDeLlamada['iDisplayLength'];
	
		$totalFiltro = 0;
	
		$connection = Yii::app()->db;
		// Obtiene los registros.
		$sql = "SELECT apor_codigo_pk, apor_razonsocial, apor_denominacion, apor_rif, apor_direccion, datos_actualizados FROM sidcai_aportante $consulta $ordenado OFFSET $offset LIMIT $limit";
		$command = $connection->createCommand();
		$command->text = $sql;
		$model = $command->queryAll();
	
		// Obtiene el numero de registro filtrados
		$sqlCount = "SELECT COUNT(*) FROM sidcai_aportante $consulta";
		$command = $connection->createCommand();
		$command->text = $sqlCount;
		$result = $command->queryAll();
		$totalFiltro = $result[0]['count'];
	
		$aaData = [];
	
		foreach($model as $m){
			$ver = '<a class="btn-acciones text-info p-2" title="Ver" href="'.Yii::app()->homeUrl.'admin/aportante/' .$m['apor_codigo_pk']. '"><i class="far fa-eye"></i></a>';
			$modificar = '<a class="btn-acciones text-warning p-2" title="Modificar" href="'.Yii::app()->homeUrl.'admin/aportante/modificar/' .$m['apor_codigo_pk']. '"><i class="fas fa-pen"></i></a>';
			$borrar = '<a class="btn-acciones text-danger p-2" title="Eliminar" href="" data-toggle="modal" data-target=".bd-example-modal-sm" onclick="eliminar(' .$m['apor_codigo_pk']. ')"><i class="fas fa-times"></i></a>';
	
			// Badge para datos actualizados
			if ($m['datos_actualizados'] == true || $m['datos_actualizados'] === 't' || $m['datos_actualizados'] == 1) {
				$badge = '<span class="badge badge-success">Actualizado</span>';
			} else {
				$badge = '<span class="badge badge-secondary">No actualizado</span>';
			}
	
			$aaData[] = [
				$m['apor_codigo_pk'],
				$m['apor_rif'],
				$m['apor_razonsocial'],
				$m['apor_denominacion'],
				$m['apor_direccion'],
				$badge,
				$ver.$modificar.$borrar
			];
		}
	
		$aData = [
			'sEcho' => intval($datosDeLlamada['sEcho']),
			'iTotalRecords' => strval($nTotal),
			'iTotalDisplayRecords' => strval($totalFiltro),
			'aaData' => $aaData
		];
	
		// Verificar integridad del JSON
		$json = json_encode($aData);
		if ($json === false) {
			$error = json_last_error_msg();
			echo json_encode(['error' => 'JSON encoding failed: ' . $error]);
		} else {
			echo $json;
		}
		
		Yii::app()->end();
	}

	public function actionEnviarCorreosNoActualizados5()
{
    $aportantes = Yii::app()->db->createCommand("
        SELECT apor_codigo_pk, apor_rif, apor_razonsocial
        FROM sidcai_aportante
        WHERE datos_actualizados IS FALSE OR datos_actualizados = 0
    ")->queryAll();

    foreach ($aportantes as $a) {
        // Aquí usarías tu función de PHPMailer o lo que tengas para enviar.
        // Ejemplo:
         FuncionesController::enviarCorreo($a['apor_rif'], "Actualiza tus datos", $mensaje);
    }

    echo json_encode(['mensaje' => 'Correos enviados a ' . count($aportantes) . ' aportantes.']);
    Yii::app()->end();
}


	public function actionObtenerDatos27(){
		// Headers para JSON
		header('Content-Type: application/json');
		
		// Código obtenido de: https://eldesvandejose.com/2016/12/05/el-plugin-datatables-v-consumiendo-datos-externos/
		// Se adaptaron algunas partes para funcionar con el proyecto y con postgresql.
	
		$nTotal = SidcaiAportante::model()->count();
	
		// Nombre de las columnas de la BD que se mostraran en la tabla
		$columnasParaRetorno = [
			'apor_codigo_pk', 
			'apor_rif',
			'apor_razonsocial', 
			'apor_denominacion',
			'apor_direccion',
			'datos_actualizados',
			'acciones'
		];
	
		$datosDeLlamada = $_GET;
	
		/* PREPARAMOS EL FILTRADO POR COLUMNAS PARA LA CAJA DE BUSQUEDA */
	
		$consulta = "";
		$parametros = [];
	
		if (isset($datosDeLlamada['sSearch']) && $datosDeLlamada['sSearch'] !== "") {
			$condiciones = [];
			
			for($i = 0; $i < count($columnasParaRetorno); $i++) {
				if (isset ($datosDeLlamada['bSearchable_'.$i]) && $datosDeLlamada['bSearchable_'.$i] == 'true') {
					
					$columna = $columnasParaRetorno[$i];
					
					// If que se coloca para evitar problemas con la columna "Acciones".
					if($columna == "acciones") {
						$columna = "apor_codigo_pk";
					}
					
					// Manejo especial para el campo booleano datos_actualizados
					if($columna == "datos_actualizados") {
						$searchTerm = strtolower(trim($datosDeLlamada['sSearch']));
						
						if (strpos($searchTerm, 'actualizado') !== false || 
							strpos($searchTerm, 'si') !== false || 
							strpos($searchTerm, 'true') !== false ||
							strpos($searchTerm, 'verdadero') !== false ||
							strpos($searchTerm, '1') !== false) {
							$condiciones[] = "datos_actualizados = true";
						} elseif (strpos($searchTerm, 'no actualizado') !== false || 
								 strpos($searchTerm, 'no') !== false || 
								 strpos($searchTerm, 'false') !== false ||
								 strpos($searchTerm, 'falso') !== false ||
								 strpos($searchTerm, '0') !== false) {
							$condiciones[] = "datos_actualizados = false";
						}
					} else {
						// Para las demás columnas, búsqueda normal
						$condiciones[] = " CAST(".$columna." AS text) ILIKE :searchTerm";
					}
				}
			}
			
			if (!empty($condiciones)) {
				$consulta = "WHERE " . implode(" OR ", $condiciones);
				$parametros[':searchTerm'] = '%' . addslashes($datosDeLlamada['sSearch']) . '%';
			}
		}
	
		// Regla de ordenación
		$ordenado = "";
	
		if (isset($datosDeLlamada['iSortCol_0'] )) {
			$columnasDeOrdenacion = intval($datosDeLlamada['iSortingCols']);
			for($i = 0; $i < $columnasDeOrdenacion; $i ++) {
				if ($datosDeLlamada['bSortable_'.intval($datosDeLlamada['iSortCol_'.$i])] == 'true') {
					$columnaOrden = $columnasParaRetorno[intval($datosDeLlamada['iSortCol_'.$i])];
					if($columnaOrden == "acciones")
						$columnaOrden = "apor_codigo_pk";
	
					$ordenado = $columnaOrden . ($datosDeLlamada['sSortDir_'.$i] === 'asc'?' asc':' desc'); 
					break;
				}
			}
	
			$ordenado = "ORDER BY " . $ordenado;
		}
	
		$offset = $datosDeLlamada['iDisplayStart'];
		$limit  = $datosDeLlamada['iDisplayLength'];
	
		$totalFiltro = 0;
	
		$connection = Yii::app()->db;
		
		// Obtiene los registros.
		$sql = "SELECT apor_codigo_pk, apor_razonsocial, apor_denominacion, apor_rif, apor_direccion, datos_actualizados 
				FROM sidcai_aportante $consulta $ordenado OFFSET $offset LIMIT $limit";
		
		$command = $connection->createCommand($sql);
		foreach ($parametros as $key => $value) {
			$command->bindValue($key, $value);
		}
		$model = $command->queryAll();
	
		// Obtiene el numero de registro filtrados
		$sqlCount = "SELECT COUNT(*) FROM sidcai_aportante $consulta";
		$command = $connection->createCommand($sqlCount);
		foreach ($parametros as $key => $value) {
			$command->bindValue($key, $value);
		}
		$totalFiltro = $command->queryScalar();
	
		$aaData = [];
	
		foreach($model as $m){
			$ver = '<a class="btn-acciones text-info p-2" title="Ver" href="'.Yii::app()->homeUrl.'admin/aportante/' .$m['apor_codigo_pk']. '"><i class="far fa-eye"></i></a>';
			$modificar = '<a class="btn-acciones text-warning p-2" title="Modificar" href="'.Yii::app()->homeUrl.'admin/aportante/modificar/' .$m['apor_codigo_pk']. '"><i class="fas fa-pen"></i></a>';
			$borrar = '<a class="btn-acciones text-danger p-2" title="Eliminar" href="" data-toggle="modal" data-target=".bd-example-modal-sm" onclick="eliminar(' .$m['apor_codigo_pk']. ')"><i class="fas fa-times"></i></a>';
	
			// Badge para datos actualizados
			if ($m['datos_actualizados'] == true || $m['datos_actualizados'] === 't' || $m['datos_actualizados'] == 1) {
				$badge = '<span class="badge badge-success">Actualizado</span>';
			} else {
				$badge = '<span class="badge badge-danger">No actualizado</span>';
			}
	
			$aaData[] = [
				$m['apor_codigo_pk'],
				$m['apor_rif'],
				$m['apor_razonsocial'],
				$m['apor_denominacion'],
				$m['apor_direccion'],
				$badge,
				$ver.$modificar.$borrar
			];
		}
	
		$aData = [
			'sEcho' => intval($datosDeLlamada['sSearch']),
			'iTotalRecords' => strval($nTotal),
			'iTotalDisplayRecords' => strval($totalFiltro),
			'aaData' => $aaData
		];
	
		// Verificar integridad del JSON
		$json = json_encode($aData);
		if ($json === false) {
			$error = json_last_error_msg();
			echo json_encode(['error' => 'JSON encoding failed: ' . $error]);
		} else {
			echo $json;
		}
		
		Yii::app()->end();
	}

	/*********************************************************************************************

											Funciones

	*********************************************************************************************/


	/**
	 * Returns the data model based on the primary key given in the GET variable.
	 * If the data model is not found, an HTTP exception will be raised.
	 * @param integer $id the ID of the model to be loaded
	 * @return SidcaiAportante the loaded model
	 * @throws CHttpException
	 */
	public function loadModel(int $id){
		$model = SidcaiAportante::model()->findByPk($id);

		if($model === null)
			throw new CHttpException(404,'La página no existe');

		return $model;
	}

	/**
	 * Performs the AJAX validation.
	 * @param SidcaiAportante $model the model to be validated
	 */
	protected function performAjaxValidation($model){
		if(isset($_POST['ajax']) && $_POST['ajax']==='sidcai-aportante-form'){
			echo CActiveForm::validate($model);
			Yii::app()->end();
		}
	}

	/**
		* Función para guardar un registro tango en agregar como en modificar.
		* Función llamada en "actionAgregar" y en "actionModificar".
		* @return array("alert", "mensaje", "(solo en $model->save()) agregar : modificar")
	**/

	/**
 * Función para guardar un registro tango en agregar como en modificar.
 * Función llamada en "actionAgregar" y en "actionModificar".
 * @return array("alert", "mensaje", "(solo en $model->save()) agregar : modificar")
**/
/**
 * Función para guardar un registro tanto en agregar como en modificar.
 * Función llamada en "actionAgregar" y en "actionModificar".
 * @return array("alert", "mensaje", "(solo en $model->save()) agregar : modificar")
**/
private function guardar($model, array $post, string $accion, int $id) : array{
    // Se importa el controlador FuncionesController para hacer uso de "erroresModel".
    Yii::import("application.controllers.FuncionesController");

    $atributos = [];
    // Se limpia los campos para evitar Ataque XSS.
    foreach($post as $key => $value){
        $atributos[$key] = mb_strtoupper(CHtml::encode($value));
    }

    $model->attributes = $atributos;

    $msj_error ="Por favor verifique el siguiente campo:<br><br>";

    // Se valida primero el $model
    if(!$model->validate()) {
        $errores = FuncionesController::erroresModel($model, "SidcaiAportante");
        return ["warning", $msj_error.$errores];
    }
    // Una vez validado el $model se proceden a validar los datos.
    if(!is_numeric($model->apor_rif)) 
        return ["warning", $msj_error."<b>".$model::attributeLabels()['apor_rif'].":</b>Ingresó un RIF no válido."];
    if($model->apor_rif == 0) 
        return ["warning", $msj_error."<b>".$model::attributeLabels()['apor_rif'].":</b> Ingresó un RIF no válido."];
    if(strpos($model->apor_correoelectronico, "@") !== false) 
        return ['warning', $msj_error.'<b>'.$model::attributeLabels()['apor_correoelectronico'].':</b> No ingrese el caracter "@".'];

    if($model->apor_fechacreacionempresa == "" || $model->apor_fechacreacionempresa == "00/00/0000"){
        return ['warning', $msj_error.'<b>'.$model::attributeLabels()['apor_fechacreacionempresa'].':</b> Ingrese la fecha de inscripción del RIF.'];
    }

    $model->apor_rif               = $model->tipo_documento.$model->apor_rif;
    $model->apor_correoelectronico  = $model->apor_correoelectronico."@GMAIL.COM";
    $model->apor_fechacreacionempresa = FuncionesController::convertirFecha($model->apor_fechacreacionempresa, "yyyy-mm-dd");

    if($accion == "agregar"){
        $msj_accion = "agregó";
        // Para agregar, establecer datos_actualizados como true por defecto
        $model->datos_actualizados = true;
    }else{
        $date = new DateTime("now", new DateTimeZone('America/Caracas'));

        // Se crea un nuevo model para guardar solo los campos que se pueden modificar.
        $model_guardar = $this->loadModel($model->apor_codigo_pk);
        $model_guardar->scenario = "modificar";

        $model_guardar->tipo_documento          = $model->tipo_documento;
        $model_guardar->apor_rif                = $model->apor_rif;
        $model_guardar->apor_fechacreacionempresa = $model->apor_fechacreacionempresa;
        $model_guardar->apor_razonsocial        = $model->apor_razonsocial;
        $model_guardar->apor_denominacion       = $model->apor_denominacion;
        
        // 🔹 REMOVER campos de alícuota que ahora se guardan en SidcaiAporAlicuota
        // $model_guardar->apor_tipoempresa        = $model->apor_tipoempresa;
        // $model_guardar->apor_actividad_economica = $model->apor_actividad_economica;
        // $model_guardar->apor_porcprivada        = $model->apor_porcprivada;
        // $model_guardar->apor_porcpublico        = $model->apor_porcpublico;
        
        $model_guardar->ciiu_codigo_fk          = $model->ciiu_codigo_fk;
        $model_guardar->esta_codigo_fk          = $model->esta_codigo_fk;
        $model_guardar->muni_codigo_fk          = $model->muni_codigo_fk;
        $model_guardar->parr_codigo_fk          = $model->parr_codigo_fk;
        $model_guardar->apor_ciudad             = $model->apor_ciudad;
        $model_guardar->apor_direccion          = $model->apor_direccion;
        $model_guardar->apor_zonapostal         = $model->apor_zonapostal;
        $model_guardar->apor_telefono1          = $model->apor_telefono1;
        $model_guardar->apor_telefono2          = $model->apor_telefono2;
        $model_guardar->apor_correoelectronico  = $model->apor_correoelectronico;
        $model_guardar->apor_diacierre          = $model->apor_diacierre;
        $model_guardar->apor_mescierre          = $model->apor_mescierre;
        $model_guardar->repr_codigo_fk          = $model->repr_codigo_fk;
        $model_guardar->esta_codigoestatus_fk   = $model->esta_codigoestatus_fk;
        $model_guardar->estatus_conciliacion    = $model->estatus_conciliacion;
        $model_guardar->apor_fechahoramodif     = $date->format('Y-m-d H:i:s');

        // 🔹 ACTUALIZAR datos_actualizados a TRUE
        $model_guardar->datos_actualizados = true;

        $model_guardar->audit_usua = Yii::app()->user->id; // Último usuario en modificar le registro.
        $msj_accion = "modificó";
    }

    // Se guardan los datos
    if($accion == "agregar"){
        if($model->save())
            $guardar = ["success", "Se $msj_accion el Aportante correctamente.", $accion];
        else
            $guardar = ["danger", "No se logró $accion al Aportante."];
    } else {
        if($model_guardar->save())
            $guardar = ["success", "Se $msj_accion el Aportante correctamente.", $accion];
        else
            $guardar = ["danger", "No se logró $accion al Aportante."];
    }

    unset($_POST['SidcaiAportante']); // Se limpia el POST enviado por el formulario.
    $model->unsetAttributes(); // Se limpia el model.
    if(isset($model_guardar)) {
        $model_guardar->unsetAttributes(); // Se limpia el model.
    }

    return $guardar;
}

	private function guardar1511($model, array $post, string $accion, int $id) : array{
		// Se importa el controlador FuncionesController para hacer uso de "erroresModel".
		Yii::import("application.controllers.FuncionesController");

		$atributos = [];
		// Se limpia los campos para evitar Ataque XSS.
		foreach($post as $key => $value){
			$atributos[$key] = mb_strtoupper(CHtml::encode($value));
		}

		$model->attributes = $atributos;

		$msj_error ="Por favor verifique el siguiente campo:<br><br>";


		// Se valida primero el $model
		if(!$model->validate()) {
			$errores = FuncionesController::erroresModel($model, "SidcaiAportante");
			return ["warning", $msj_error.$errores];
		}
		// Una vez validado el $model se proceden a validar los datos.
		if(!is_numeric($model->apor_rif)) 
			return ["warning", $msj_error."<b>".$model::attributeLabels()['apor_rif'].":</b>Ingresó un RIF no válido."];
		if($model->apor_rif == 0) 
			return ["warning", $msj_error."<b>".$model::attributeLabels()['apor_rif'].":</b> Ingresó un RIF no válido."];
		if(strpos($model->apor_correoelectronico, "@") !== false) 
			return ['warning', $msj_error.'<b>'.$model::attributeLabels()['apor_correoelectronico'].':</b> No ingrese el caracter "@".'];

		if($model->apor_fechacreacionempresa == "" || $model->apor_fechacreacionempresa == "00/00/0000"){
			return ['warning', $msj_error.'<b>'.$model::attributeLabels()['apor_fechacreacionempresa'].':</b> Ingrese la fecha de inscripción del RIF.'];
		}

		$model->apor_rif 				= $model->tipo_documento.$model->apor_rif;
		$model->apor_correoelectronico  = $model->apor_correoelectronico."@GMAIL.COM";
		$model->apor_fechacreacionempresa = FuncionesController::convertirFecha($model->apor_fechacreacionempresa, "yyyy-mm-dd");

		if($accion == "agregar"){
			$msj_accion = "agregó";
		}else{
			$date = new DateTime("now", new DateTimeZone('America/Caracas'));

			// Se crea un nuevo model para guardar solo los campos que se pueden modificar.
			$model_guardar = $this->loadModel($model->apor_codigo_pk);
			$model_guardar->scenario = "modificar";

			$model_guardar->tipo_documento			= $model->tipo_documento;
			$model_guardar->apor_rif 				= $model->apor_rif;
			$model_guardar->apor_fechacreacionempresa = $model->apor_fechacreacionempresa;
			$model_guardar->apor_razonsocial 		= $model->apor_razonsocial;
			$model_guardar->apor_denominacion 		= $model->apor_denominacion;
			$model_guardar->apor_tipoempresa 		= $model->apor_tipoempresa;
			$model_guardar->ciiu_codigo_fk 			= $model->ciiu_codigo_fk;
			$model_guardar->esta_codigo_fk 			= $model->esta_codigo_fk;
			$model_guardar->muni_codigo_fk 			= $model->muni_codigo_fk;
			$model_guardar->parr_codigo_fk 			= $model->parr_codigo_fk;
			$model_guardar->apor_ciudad 			= $model->apor_ciudad;
			$model_guardar->apor_direccion 			= $model->apor_direccion;
			$model_guardar->apor_zonapostal 		= $model->apor_zonapostal;
			$model_guardar->apor_telefono1 			= $model->apor_telefono1;
			$model_guardar->apor_telefono2 			= $model->apor_telefono2;
			$model_guardar->apor_correoelectronico 	= $model->apor_correoelectronico;
			$model_guardar->apor_diacierre 			= $model->apor_diacierre;
			$model_guardar->apor_mescierre 			= $model->apor_mescierre;
			$model_guardar->repr_codigo_fk 			= $model->repr_codigo_fk;
			$model_guardar->esta_codigoestatus_fk 	= $model->esta_codigoestatus_fk;
			$model_guardar->estatus_conciliacion 	= $model->estatus_conciliacion;

			//ajustes alicuota 14-07-2025
			$model_guardar->apor_actividad_economica 	= $model->apor_actividad_economica;
			$model_guardar->apor_porcprivada 	= $model->apor_porcprivada;
			$model_guardar->apor_porcpublico 	= $model->apor_porcpublico;
			$model_guardar->apor_fechahoramodif     = $date->format('Y-m-d H:i:s');

			$model_guardar->audit_usua = Yii::app()->user->id; // Último usuario en modificar le registro.
			$msj_accion = "modificó";
		}

		// Se guardan los datos
		if($model_guardar->save())
			$guardar = ["success", "Se $msj_accion el Aportante correctamente.", $accion];
		else
			$guardar = ["danger", "No se logró $accion al Aportante."];

		unset($_POST['SidcaiAportante']); // Se limpia el POST enviado por el formulario.
		$model->unsetAttributes(); // Se limpia el model.
		$model_guardar->unsetAttributes(); // Se limpia el model.

		return $guardar;
	}

	/*********************************************************************************************

											Expresiones

	*********************************************************************************************/


// En AportanteController.php
public function actionObtenerAlicuotaActual($cod_aportante) {
$alicuota = SidcaiAporAlicuota::model()->find(array(
	'condition' => 'cod_aportante = :cod AND estatus = :estatus',
	'params' => array(
		':cod' => $cod_aportante,
		':estatus' => SidcaiAporAlicuota::ESTATUS_ACTIVO
	),
	'order' => 'fecha_registro DESC'
));

echo CJSON::encode(array(
	'alicuota' => $alicuota ? $alicuota->alicuota : 0,
	'estatus' => $alicuota ? $alicuota->estatus : null
));
Yii::app()->end();
}

public function actionObtenerActividadesPorTipoEmpresa()
{
if (isset($_POST['tipo_empresa_id'])) {
	$tipoEmpresaId = (int) $_POST['tipo_empresa_id'];
	$actividades = SidcaiActividadEconomica::model()->findAllByAttributes([
		'tipo_empresa_id' => $tipoEmpresaId
	]);

	$data = CHtml::listData($actividades, 'act_codigo_pk', 'act_actividad_economica');

	foreach ($data as $value => $nombre) {
		echo CHtml::tag('option', ['value' => $value], CHtml::encode($nombre), true);
	}
}
}

public function actionCheckStatus() {
if (Yii::app()->request->isPostRequest) {
	$id = Yii::app()->request->getPost('id');
	$exists = SidcaiAporAlicuota::model()->exists([
		'condition' => 'cod_aportante = :id AND estatus = 4',
		'params' => [':id' => $id]
	]);
	echo CJSON::encode(['exists' => $exists]);
	Yii::app()->end();
}
throw new CHttpException(400, 'Solicitud inválida');
}

public function actionActualizarAlicuotas()
{
    try {
        $resultado = SidcaiAporAlicuota::model()->verificarAlicuotasTodos();
        Yii::log("ADMIN ingresó. Se verificaron alícuotas: $resultado registros actualizados", 'info', 'alicuotas');

        // 👉 Redireccionar al index
        $this->redirect(array('index')); 
        // o si es un módulo admin:
        // $this->redirect(array('admin/index'));

    } catch (Exception $e) {
        Yii::log("Error verificando alícuotas al ingresar admin: " . $e->getMessage(), 'error', 'alicuotas');

        // Si quieres que igual regrese al index en caso de error:
        $this->redirect(array('index'));
    }
}

public function actionGuardarEstatus2009() {
    if (!Yii::app()->request->isPostRequest) {
        throw new CHttpException(400, 'Petición inválida');
    }

    header('Content-Type: application/json');
    $response = ['success' => false, 'message' => ''];

    try {
        $apor_codigo_fk = Yii::app()->request->getPost('apor_codigo_fk');
        $codigo = Yii::app()->request->getPost('codigo');
        $observaciones = Yii::app()->request->getPost('observaciones');
        $estatus_codigo_fk = 2009;
        $usuario_id_fk = Yii::app()->user->id;

        if (empty($apor_codigo_fk) || empty($codigo) || empty($observaciones)) {
            throw new Exception('Todos los campos requeridos deben ser completados.');
        }

        Yii::import('application.models.SidcaiAportante');
        Yii::import('application.models.SidcaiHistoriaHistorial');

        $aportante = SidcaiAportante::model()->findByPk($apor_codigo_fk);
        if (!$aportante) {
            throw new Exception('El aportante no existe.');
        }

        // --- Archivo obligatorio ---
        $archivo = CUploadedFile::getInstanceByName('archivo');
        if ($archivo === null) {
            throw new Exception('Debe subir un archivo para continuar.');
        }

        $allowedTypes = ['pdf', 'jpg', 'png'];
        $extension = strtolower($archivo->getExtensionName());
        if (!in_array($extension, $allowedTypes)) {
            throw new Exception('Tipo de archivo no permitido.');
        }
        if ($archivo->getSize() > 5 * 1024 * 1024) {
            throw new Exception('El archivo no puede superar 5MB.');
        }

        $nombreArchivo = 'estatus_2009_' . $apor_codigo_fk . '_' . time() . '.' . $extension;
        $rutaParaBD = null;

        // --- Intento de guardado local ---
        $rutaDirLocal = Yii::getPathOfAlias('webroot') . '/upload/' . $apor_codigo_fk . '/estatus2009';
        if (!is_dir($rutaDirLocal)) mkdir($rutaDirLocal, 0777, true);

        $rutaCompletaLocal = $rutaDirLocal . '/' . $nombreArchivo;

        if ($archivo->saveAs($rutaCompletaLocal)) {
            $rutaParaBD = 'upload/' . $apor_codigo_fk . '/estatus2009/' . $nombreArchivo;
        } else {
            // --- Intento de guardado remoto ---
            $config = require(Yii::getPathOfAlias('application.config.params_upload') . '.php');
            $remoteHost = $config['FTPSERVER'];
            $remotePort = $config['PORT'];
            $remoteUser = $config['FTPUSERNAME'];
            $remotePass = $config['FTPPASSWORD'];
            $remoteBaseDir = $config['REMOTEDIR'];
            $remoteDir = $remoteBaseDir . $apor_codigo_fk . '/estatus2009';

            $connection = @ssh2_connect($remoteHost, $remotePort);
            if (!$connection) throw new Exception('No se pudo conectar al servidor remoto.');
            if (!@ssh2_auth_password($connection, $remoteUser, $remotePass)) {
                throw new Exception('No se pudo autenticar en el servidor remoto.');
            }

            $sftp = ssh2_sftp($connection);
            if (!$sftp) throw new Exception('No se pudo inicializar SFTP.');

            // Crear directorios remotos
            $dirs = explode('/', trim($remoteDir, '/'));
            $path = '';
            foreach ($dirs as $d) {
                $path .= '/' . $d;
                if (!@ssh2_sftp_stat($sftp, $path)) {
                    ssh2_sftp_mkdir($sftp, $path, 0777, true);
                }
            }

            // Guardar archivo temporal
            $tempPath = sys_get_temp_dir() . '/' . $nombreArchivo;
            if (!$archivo->saveAs($tempPath)) {
                throw new Exception('Error guardando archivo temporal para subida remota.');
            }

            $remotePath = $remoteDir . '/' . $nombreArchivo;
            if (!@ssh2_scp_send($connection, $tempPath, $remotePath, 0644)) {
                unlink($tempPath);
                throw new Exception('Error subiendo archivo al servidor remoto.');
            }
            unlink($tempPath);

            $rutaParaBD = 'upload/' . $apor_codigo_fk . '/estatus2009/' . $nombreArchivo;
        }

        // --- Validar que exista la ruta antes de guardar historial ---
        if (empty($rutaParaBD)) {
            throw new Exception('No se pudo guardar el archivo, operación cancelada.');
        }

        // --- Guardar historial ---
        $historial = new SidcaiHistoriaHistorial();
        $historial->apor_codigo_fk = $apor_codigo_fk;
        $historial->codigo = $codigo;
        $historial->observaciones = $observaciones;
        $historial->archivo = $rutaParaBD;
        $historial->estatus_codigo_fk = $estatus_codigo_fk;
        $historial->usuario_id_fk = $usuario_id_fk;

        if (!$historial->save()) {
            throw new Exception('Error guardando historial: ' . print_r($historial->getErrors(), true));
        }

        // Actualizar estatus del aportante
        $aportante->esta_codigoestatus_fk = $estatus_codigo_fk;
        $aportante->save(false, ['esta_codigoestatus_fk']);

        $response = [
            'success' => true,
            'message' => 'Archivo subido y estatus actualizado correctamente.',
            'archivo' => $rutaParaBD
        ];

    } catch (Exception $e) {
        $response['message'] = $e->getMessage();
    }

    echo json_encode($response);
    Yii::app()->end();
}



public function actionGuardarEstatus2009_10112025() {
    if (!Yii::app()->request->isPostRequest) {
        throw new CHttpException(400, 'Petición inválida');
    }

    $response = ['success'=>false,'message'=>''];

    try {
        $apor_codigo_fk = Yii::app()->request->getPost('apor_codigo_fk');
        $codigo = Yii::app()->request->getPost('codigo');
        $observaciones = Yii::app()->request->getPost('observaciones');
        $estatus_codigo_fk = 2009;
        $usuario_id_fk = Yii::app()->user->id;

        if (empty($apor_codigo_fk) || empty($codigo) || empty($observaciones)) {
            $response['message'] = 'Todos los campos requeridos deben ser completados';
            echo json_encode($response); Yii::app()->end();
        }

        Yii::import('application.models.SidcaiAportante');
        Yii::import('application.models.SidcaiHistoriaHistorial');
        Yii::import('application.controllers.FuncionesController');

        $aportante = SidcaiAportante::model()->findByPk($apor_codigo_fk);
        if (!$aportante) {
            $response['message'] = 'El aportante no existe';
            echo json_encode($response); Yii::app()->end();
        }

        $archivo_nombre = null;
        $archivo = CUploadedFile::getInstanceByName('archivo');

        if ($archivo !== null) {
            $allowedTypes = ['pdf','jpg','png'];
            $extension = strtolower($archivo->getExtensionName());

            if (!in_array($extension,$allowedTypes)) {
                $response['message'] = 'Archivo no permitido';
                echo json_encode($response); Yii::app()->end();
            }

            if ($archivo->getSize() > 5*1024*1024) {
                $response['message'] = 'Archivo mayor a 5MB';
                echo json_encode($response); Yii::app()->end();
            }

            $ruta_local = Yii::getPathOfAlias('webroot.upload') . '/' . $apor_codigo_fk;
            $existe_local = FuncionesController::checkPathAndFile($ruta_local);
            $archivo_nombre = 'estatus_2009_' . $apor_codigo_fk . '_' . time() . '.' . $extension;

			// Si existe localmente, subir a servidor remoto
			//print_r($existe_local);die();

            if ($existe_local == "si") {
                if (!is_dir($ruta_local)) mkdir($ruta_local, 0777, true);
                $ruta_local .= '/estatus2009';
                if (!is_dir($ruta_local)) mkdir($ruta_local, 0777, true);
                $archivo->saveAs($ruta_local.'/'.$archivo_nombre);
            } else {
                $remoteDir = Yii::app()->params['REMOTEDIR'] . $apor_codigo_fk . '/estatus2009';
                $archivo_nombre = FuncionesController::subirRecaudoSsh(
                    new SidcaiRecaudo(),
                    $archivo,
                    8,
                    $remoteDir,
                    $allowedTypes,
                    'estatus2009',
                    false
                );
            }
        }

        $historial = new SidcaiHistoriaHistorial();
        $historial->apor_codigo_fk = $apor_codigo_fk;
        $historial->codigo = $codigo;
        $historial->observaciones = $observaciones;
        $historial->archivo = $archivo_nombre;
        $historial->estatus_codigo_fk = $estatus_codigo_fk;
        $historial->usuario_id_fk = $usuario_id_fk;

        if ($historial->save()) {
            $aportante->esta_codigoestatus_fk = $estatus_codigo_fk;
            $aportante->save(false,['esta_codigoestatus_fk']);
            $response['success'] = true;
            $response['message'] = 'Guardado y estatus actualizado correctamente';
            $response['historia_id'] = $historial->historia_id;
        } else {
            $response['message'] = 'Error guardando historial: '.implode(', ',$historial->getErrors());
        }

    } catch (Exception $e) {
        $response['message'] = 'Error del sistema: '.$e->getMessage();
    }

    header('Content-Type: application/json');
    echo json_encode($response);
    Yii::app()->end();
}




public function actionGuardarEstatus200956() {
    // Verificar que sea POST
    if (!Yii::app()->request->isPostRequest) {
        throw new CHttpException(400, 'Petición inválida');
    }

    $response = array('success' => false, 'message' => '');

    try {
        // Obtener datos del formulario
        $apor_codigo_fk = Yii::app()->request->getPost('apor_codigo_fk');
        $codigo = Yii::app()->request->getPost('codigo');
        $observaciones = Yii::app()->request->getPost('observaciones');
        $estatus_codigo_fk = 2009;
        $usuario_id_fk = Yii::app()->user->id;

        // Validación básica
        if (empty($apor_codigo_fk) || empty($codigo) || empty($observaciones)) {
            $response['message'] = 'Todos los campos requeridos deben ser completados';
            echo json_encode($response);
            Yii::app()->end();
        }

        // Importar modelos
        Yii::import('application.models.SidcaiAportante');
        Yii::import('application.models.SidcaiHistoriaHistorial');

        // Verificar aportante
        $aportante = SidcaiAportante::model()->findByPk($apor_codigo_fk);
        if (!$aportante) {
            $response['message'] = 'El aportante no existe';
            echo json_encode($response);
            Yii::app()->end();
        }

        // Manejo de archivo opcional
        $archivo_nombre = null;
        $archivo = CUploadedFile::getInstanceByName('archivo');

        if ($archivo !== null) {
            $allowedTypes = ['pdf', 'jpg', 'png'];
            $extension = strtolower($archivo->getExtensionName());

            if (!in_array($extension, $allowedTypes)) {
                $response['message'] = 'Tipo de archivo no permitido. Solo se aceptan PDF, JPG, PNG';
                echo json_encode($response);
                Yii::app()->end();
            }

            if ($archivo->getSize() > 5 * 1024 * 1024) {
                $response['message'] = 'El archivo no puede ser mayor a 5MB';
                echo json_encode($response);
                Yii::app()->end();
            }

            $archivo_nombre = 'estatus_2009_' . $apor_codigo_fk . '_' . time() . '.' . $extension;
            $ruta_archivo = Yii::getPathOfAlias('webroot.upload') . '/' . $archivo_nombre;

            if (!is_dir(dirname($ruta_archivo))) {
                mkdir(dirname($ruta_archivo), 0777, true);
            }

            if (!$archivo->saveAs($ruta_archivo)) {
                $response['message'] = 'Error al guardar el archivo';
                echo json_encode($response);
                Yii::app()->end();
            }
        }

        // Guardar historial
        $historial = new SidcaiHistoriaHistorial();
        $historial->apor_codigo_fk = $apor_codigo_fk;
        $historial->codigo = $codigo;
        $historial->observaciones = $observaciones;
        $historial->archivo = $archivo_nombre;
        $historial->estatus_codigo_fk = $estatus_codigo_fk;
        $historial->usuario_id_fk = $usuario_id_fk;

        if ($historial->save()) {
            // Actualizar estatus del aportante
            $aportante->esta_codigoestatus_fk = $estatus_codigo_fk;
            if ($aportante->save(false, ['esta_codigoestatus_fk'])) {
                $response['success'] = true;
                $response['message'] = 'Información guardada y estatus del aportante actualizado correctamente';
            } else {
                $response['success'] = true;
                $response['message'] = 'Información guardada, pero no se pudo actualizar el estatus del aportante';
            }
            $response['historia_id'] = $historial->historia_id;
        } else {
            $response['message'] = 'Error al guardar en la base de datos: ' . implode(', ', $historial->getErrors());
            if ($archivo_nombre && file_exists($ruta_archivo)) {
                unlink($ruta_archivo);
            }
        }

    } catch (Exception $e) {
        $response['message'] = 'Error del sistema: ' . $e->getMessage();
        if (isset($archivo_nombre) && isset($ruta_archivo) && file_exists($ruta_archivo)) {
            unlink($ruta_archivo);
        }
    }

    // Devolver respuesta JSON
    header('Content-Type: application/json');
    echo json_encode($response);
    Yii::app()->end();
}





// CAMBIA el nombre de la acción a TODO MINÚSCULAS
public function actionGuardarEstatus200966() {
    // Verificar que sea una petición POST
   /* if (!Yii::app()->request->isPostRequest) {
        throw new CHttpException(400, 'Petición inválida');
    }*/

    $response = array('success' => false, 'message' => '');
    
    try {
        // Obtener datos del formulario
        $apor_codigo_fk = Yii::app()->request->getPost('apor_codigo_fk');
        $codigo = Yii::app()->request->getPost('codigo');
        $observaciones = Yii::app()->request->getPost('observaciones');
        $estatus_codigo_fk = 2009;
        $usuario_id_fk = Yii::app()->user->id;

        // Validaciones básicas
        if (empty($apor_codigo_fk) || empty($codigo) || empty($observaciones)) {
            $response['message'] = 'Todos los campos requeridos deben ser completados';
            echo json_encode($response);
            Yii::app()->end();
        }

        // IMPORTANTE: Importar los modelos necesarios
        Yii::import('application.models.Aportante');
        Yii::import('application.models.SidcaiHistoriaHistorial');

        // Validar que el aportante existe
        $aportante = Aportante::model()->findByPk($apor_codigo_fk);
        if (!$aportante) {
            $response['message'] = 'El aportante no existe';
            echo json_encode($response);
            Yii::app()->end();
        }

        // Procesar archivo si se subió
        $archivo_nombre = null;
        $archivo = CUploadedFile::getInstanceByName('archivo');
        
        if ($archivo !== null) {
            // Validar tipo de archivo
            $allowedTypes = array('pdf', 'jpg', 'png', 'docx');
            $extension = strtolower($archivo->getExtensionName());
            
            if (!in_array($extension, $allowedTypes)) {
                $response['message'] = 'Tipo de archivo no permitido. Solo se aceptan PDF, JPG, PNG, DOCX';
                echo json_encode($response);
                Yii::app()->end();
            }

            // Validar tamaño (máximo 5MB)
            if ($archivo->getSize() > 5 * 1024 * 1024) {
                $response['message'] = 'El archivo no puede ser mayor a 5MB';
                echo json_encode($response);
                Yii::app()->end();
            }

            // Generar nombre único para el archivo
            $archivo_nombre = 'estatus_2009_' . $apor_codigo_fk . '_' . time() . '.' . $extension;
            $ruta_archivo = Yii::getPathOfAlias('webroot.upload') . '/' . $archivo_nombre;

            // Crear directorio si no existe
            $uploadDir = dirname($ruta_archivo);
            if (!is_dir($uploadDir)) {
                mkdir($uploadDir, 0777, true);
            }

            // Guardar archivo
            if (!$archivo->saveAs($ruta_archivo)) {
                $response['message'] = 'Error al guardar el archivo';
                echo json_encode($response);
                Yii::app()->end();
            }
        }

        // Guardar en la base de datos
        $historial = new SidcaiHistoriaHistorial();
        $historial->apor_codigo_fk = $apor_codigo_fk;
        $historial->codigo = $codigo;
        $historial->observaciones = $observaciones;
        $historial->archivo = $archivo_nombre;
        $historial->estatus_codigo_fk = $estatus_codigo_fk;
        $historial->usuario_id_fk = $usuario_id_fk;

        if ($historial->save()) {
            $response['success'] = true;
            $response['message'] = 'Información guardada correctamente';
            $response['historia_id'] = $historial->historia_id;
        } else {
            $response['message'] = 'Error al guardar en la base de datos: ' . implode(', ', $historial->getErrors());
            
            // Si hubo error, eliminar archivo subido (si existe)
            if ($archivo_nombre && file_exists($ruta_archivo)) {
                unlink($ruta_archivo);
            }
        }

    } catch (Exception $e) {
        $response['message'] = 'Error del sistema: ' . $e->getMessage();
        
        // Limpiar archivo en caso de error
        if (isset($archivo_nombre) && isset($ruta_archivo) && file_exists($ruta_archivo)) {
            unlink($ruta_archivo);
        }
    }

    // Devolver respuesta JSON
    header('Content-Type: application/json');
    echo json_encode($response);
    Yii::app()->end();
}




}



?>