<?php 

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;


/*
	Controlador que sirve para albergar funciones que se utilizan varias veces en otros Controladores.
*/

class FuncionesController extends Controller{

	private static function plantilla_mensaje(string $cuerpo_mensaje) : string{
		/*	HEAD	*/
		$mensaje = '<html>';
        $mensaje .= '<table width="100%" border="0" cellspacing="0" cellpadding="0" style="background-color:#ffffff">';

        $mensaje .= '<tr>';
        //$mensaje .= '<td align="center" style="background-color: #245b99">';
        $mensaje .= '<td align="center">';
        //$mensaje .= '<img src="http://localhost/proyecto/images/barra.png">';
        //$mensaje .= '<img src="https://i92.servimg.com/u/f92/19/77/04/53/barra10.png">';
        $mensaje .= '<img src="http://sidcai.fonacit.gob.ve/images/cintillo-principal.jpg" width="100%">';
        $mensaje .= '</td >';
        $mensaje .= '</tr>';

        $mensaje .= "<tr>";
        $mensaje .= "<td style='padding-left: 60px; padding-right: 60px; padding-top:20px; text-align:center'>";
        $mensaje .= "<h2>SIDCAI</h2>";
        $mensaje .= "</td>";
        $mensaje .= "</tr>";

        $mensaje .= '<tr>';
        $mensaje .= '<td height="16" colspan="3" style="padding-left: 60px; padding-right: 60px;">';
        $mensaje .= '<hr color="#000066">';
        $mensaje .= '</td>';
        $mensaje .= '</tr>';


        /*  FIN HEAD  */

        /*  BODY  */
        $mensaje .= "<tr>";
        $mensaje .= "<td style='padding-left: 60px; padding-right: 60px; padding-top:20px; padding-bottom: 20px'>";
        $mensaje .= "Estimada empresa:<br><br>";
        $mensaje .= $cuerpo_mensaje;
        $mensaje .= "</td>";
        $mensaje .= "</tr>";
        /*  FIN BODY  */

        /*  FOOTER  */
        $mensaje .= "<tr>";
        $mensaje .= "<td style='padding-left: 60px; padding-right: 60px'>";
        $mensaje .= '<p>Muchas Gracias;<br />';
        $mensaje .= '<strong>Fondo Nacional de Ciencia, Tecnología e Innovación (FONACIT).<br />';
        $mensaje .= 'Ministerio de Ciencia y Tecnología e Innovación.</strong></p><br>';
        $mensaje .= "</td>";
        $mensaje .= "</tr>";

        $mensaje .= "<tr>";
        $mensaje .= "<td style='padding-left: 60px; padding-right: 60px; padding-bottom: 30px;'>";
        $mensaje .= '<p><center>Para mayor información comuníquese con el <b>Fondo Nacional de Ciencia  Tecnología e ';
        $mensaje .= 'Innovación - FONACIT</b><br>';
        $mensaje .= 'Av. Universidad, Esquina El Chorro, Torre Ministerial, Planta Baja, Taquilla Única <br>';
        $mensaje .= 'Teléfonos: 0212-5052580 / 0212-5052548 / 0212-5054884 / 0212-5052503 / 0212-5052718.<br>';
        $mensaje .= 'Horario: Lunes a jueves 8:30 AM a 11.30 AM y 1:30 PM a 3:30 PM - Viernes 8:30 AM a 11.30 AM</center><br><br>';
        $mensaje .= '<strong>Nota:</strong> este email es una respuesta automática del sistema. No lo responda.</p>';
        $mensaje .= "</td>";
        $mensaje .= "</tr>";


        $mensaje .= '</table>';
        $mensaje .= '<html>';
        /*	FIN FOOTERs	*/

        return $mensaje;
	}


	public static function enviarCorreo(array $para, array $nombre, string $titulo, string $mensaje) : bool{
		require_once(Yii::app()->basePath . '/extensions/phpmailer/src/PHPMailer.php');
		require_once(Yii::app()->basePath . '/extensions/phpmailer/src/SMTP.php');
		require_once(Yii::app()->basePath . '/extensions/phpmailer/src/Exception.php');


		$mail = new PHPMailer;

		$usuario = Yii::app()->params['emailAtencion']; 

		$exitoso = false;

		try {
		    //Server settings
		    //Server settings
		    // $mail->SMTPDebug = SMTP::DEBUG_SERVER;                      // Enable verbose debug output
		    $mail->SMTPDebug = 0;                      // Enable verbose debug output
		    $mail->isSMTP();   
		    $mail->SMTPOptions = array(
                  'ssl' => array(
                      'verify_peer' => false,
                      'verify_peer_name' => false,
                      'allow_self_signed' => true
                  )
              );
		   /* $mail->Host       = 'saturno.fonacit.gob.ve';                    // Set the SMTP server to send through
		    $mail->SMTPAuth   = true;                                   // Enable SMTP authentication
		    $mail->Username   = $usuario;                     // SMTP username
		    $mail->CharSet 	  = 'UTF-8';
		    $mail->Password   = '4ib7nexm$$';                               // SMTP password
		    //$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;         // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
		    $mail->Port       = 25;    */                                // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above

			$Host = Yii::app()->params['Host']; 
			$SMTPAuth = Yii::app()->params['SMTPAuth']; 
			$CharSet = Yii::app()->params['CharSet']; 
			$Password = Yii::app()->params['Password']; 
			$Port = Yii::app()->params['Port']; 
			$mail->Host       = $Host;                    // Set the SMTP server to send through
		    $mail->SMTPAuth   = $SMTPAuth;                                   // Enable SMTP authentication
		    $mail->Username   = $usuario;                     // SMTP username
		    $mail->CharSet 	  = $CharSet;
		    $mail->Password   = $Password;                               // SMTP password
     	    $mail->Port       = $Port;
			//$mail->SMTPSecure = 'STARTTLS'; // o 'ssl' si es necesario 
			//$mail->SMTPDebug = 4; // Detalle alto de depuración, cambia a 4 para aún más detalles
            //$mail->AuthType = 'LOGIN';

		    //Recipients
		    $mail->setFrom($usuario, 'SIDCAI');

		    for($i = 0; $i < count($para); $i++){
	       	 	$mail->AddAddress($para[$i], $nombre[$i]); 
	        }

		    // $mail->addReplyTo('info@example.com', 'Information');
		    // $mail->addCC('cc@example.com');
		    // $mail->addBCC('bcc@example.com');

		    // Attachments
		    // $mail->addAttachment('/var/tmp/file.tar.gz');         // Add attachments
		    // $mail->addAttachment('/tmp/image.jpg', 'new.jpg');    // Optional name

		    // Content
		    $mail->isHTML(true);                                  // Set email format to HTML
		    $mail->Subject = $titulo;
		    // $mail->Body    = 'This is the HTML message body <b>in bold!</b>';
		    $mail->AltBody = '';
		    $mail->Body = self::plantilla_mensaje($mensaje);
		    if($mail->Send()){
				$exitoso = true;
			}else{
				$exitoso = false;
			}
		} catch (Exception $e) {
		    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
		}

		return $exitoso;
	}

	/* 
	Función para generar un código alfanumérico con N de longitud
	$tipo = 
	1. Numérico
	2. Alfabético
	3. Alfanumérico
	4. Alfanumérico con simbolos
	*/
	public static function generarCodigo(int $longitud, int $tipo = 1) : string{
		if($tipo == 1)
			$alpha = "1234567890";
		if($tipo == 2)
			$alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
		if($tipo == 3)
			$alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
		if($tipo == 4)
			$alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!?@#$%_-.";

		$code = "";

		for($i=0;$i<$longitud;$i++){
		    $code .= $alpha[rand(0, strlen($alpha)-1)];
		}

		return $code;
	}

	/**
		Convierte la fecha en el formato enviado por formato_salida
		$fecha_entrada  => "2000-12-31", "2000/12/31", "31-12-2000", "31/12/2000"
		$formato_salida => "yyyy-mm-dd", "yyyy/mm/dd", "dd-mm-yyyy", "dd/mm/yyyy"
		$hora 			=> Por defecto true, si es true significa que el formato de entrada vendrá con la fecha y hora
	**/
	public static function convertirFecha($fecha_entrada, $formato_salida, $hora = true){
		if($fecha_entrada != "" && $formato_salida != ""){
			// Se convierte en mayusculas para evitar inconvenientes
			$formato_salida  = strtoupper($formato_salida);
			$fecha_hora = "";

			// Primera verifica si el formato de entrada viene con hora
			if(strpos($fecha_entrada, " ") !== false){
				$fecha = explode(" ", $fecha_entrada);
				$fecha_entrada = $fecha[0];
				$fecha_hora = " ".$fecha[1];
			}

			if($hora == false)
				$fecha_hora = "";

			$fecha  = explode("/", $fecha_entrada);
			$salida = explode("/", $formato_salida);
			$salidaFormato = "/";

			if(count($fecha) < 2)
				$fecha  = explode("-", $fecha_entrada);

			if(count($salida) < 2){
				$salida = explode("-", $formato_salida);
				$salidaFormato = "-";
			}

			if(strlen($fecha[0])  == strlen($salida[0]))
				return $fecha[0].$salidaFormato.$fecha[1].$salidaFormato.$fecha[2] . $fecha_hora;
			else
				return $fecha[2].$salidaFormato.$fecha[1].$salidaFormato.$fecha[0] . $fecha_hora;
		}
	}

	/**
	 * Obtiene la moneda de la fecha solicitada.
	 */
	public static function obtenerMoneda(string $fecha) : string{
		$connection = Yii::app()->db;
		$sql = "SELECT mone_simbolo FROM sidcai_moneda WHERE to_date(:fecha,'YYYY-MM-DD') >= mone_fechainicio AND to_date(:fecha,'YYYY-MM-DD') <= (CASE WHEN mone_fechafin != null THEN mone_fechafin ELSE '2099-12-31' END) ORDER BY mone_codigo_pk DESC LIMIT 1";
		$command = $connection->createCommand();
		$command->text = $sql;
		$command->bindParam(':fecha', $fecha);
		$model = $command->queryRow();

		return ($model != null) ? $model['mone_simbolo'] : '';
	}

	/**
	 * LM Obtiene la moneda de la fecha solicitada LM.
	 */
	public static function obtenerMonedaNew(string $fecha) : string{
		$connection = Yii::app()->db;
		$sql = "SELECT mone_simbolo FROM sidcai_moneda 
		WHERE :fecha >= mone_fechainicio AND 
		:fecha <= (CASE WHEN mone_fechafin != null THEN 
		mone_fechafin ELSE '2099-12-31' END) ORDER BY mone_codigo_pk DESC LIMIT 1";
		$command = $connection->createCommand();
		$command->text = $sql;
		$command->bindParam(':fecha', $fecha);
		$model = $command->queryRow();
		//print_r($model);die();

		return ($model != null) ? $model['mone_simbolo'] : '';
	}
	//end LM


	/**
	 * Obtiene la moneda de la fecha solicitada en la unidad tributaria.
	 */
	public static function obtenerMonedaUT(string $fecha_inicio_declaracion, string $fecha_fin_declaracion) : string{
		$fecha_inicio_declaracion = date("Y-m-d", strtotime($fecha_inicio_declaracion." -1 year"));
		$criteria = new CDbCriteria;
		$criteria->condition = 'unid_habilitado = true';
		$criteria->addBetweenCondition('unid_fechacomienzo', $fecha_inicio_declaracion, $fecha_fin_declaracion);
		$criteria->order = 'unid_codigo_pk DESC';

		$unidad_tributaria = SidcaiUnidadtributaria::model()->findAll($criteria);

		$fecha_ut = "";
		$valor_UT = 0;

		if($unidad_tributaria != NULL){
			// Se suman los 183 dias a las fecha de comienzo, y aquella fecha que no supere la fecha de fin es el registro correcto.
			foreach($unidad_tributaria as $uni){
				$fecha_inicio_sumada = date("Y-m-d",strtotime($uni->unid_fechacomienzo." +183 day")); 

				if(strtotime($fecha_inicio_sumada) < strtotime($fecha_fin_declaracion)){
					$fecha_ut = $uni->unid_fechacomienzo;
					$valor_UT = $uni->unid_valor;
					break;
				}			
			}
		}

		$moneda = self:: obtenerMoneda($fecha_ut);

		return ($moneda != "") ? $moneda : '';
	}

	/**
	 * Obtiene el monto con la reconversión en la fecha dada.
	 * $fecha => Tiene que ser la fecha del monto, si el monto es del 2015, la fecha tiene que ser "2015-xx-xx", así devolverá el monto con la reconversión actual.

	 * Es importante usarlo cuando hay un monto que el Aportante tiene que pagar, esto hará que le muestre el monto con la reconverisón vigente.

	 * El parametro $no_reconversion es usado en obtenerInteresesMoratorios.
	 */
	public static function reconversion(string $fecha, float $monto, bool $no_reconversion = false) : float{
		$model = SidcaiMoneda::model()->find(
			[
				'select' => 'mone_simbolo, mone_division, mone_fechainicio',
				'order'  => 'mone_codigo_pk DESC',
				'limit'  => 1
			]
		);
		$dividir = 1;
		$devolver = 0;

		if(!$fecha){
			$dividir = $model["mone_division"];
			$devolver = $monto / $dividir;
			if(number_format($devolver, 2, ',', '.') == 0.00){
				$devolver = $monto;
			}
			/* $devolver = $monto; */
		}else{
			if($model != null && $no_reconversion == false){		
				// Se obtiene la moneda por medio de la fecha en la que se quiere saber la reconversión.
	
				$moneda = self::obtenerMoneda($fecha);
				/* var_dump($moneda); */
				/* echo "<br>";
				echo "<br>"; */
				// Con la moneda obtenida, ya se puede saber todo el registro.
				$model2 = SidcaiMoneda::model()->find('mone_simbolo = :mone_simbolo', [':mone_simbolo' => $moneda]);
		
				if($model2 != null){
					if($model->mone_simbolo != $model2->mone_simbolo){				
						// Obtendrá los registros con las cuales se harán las divisiones.
						$division = SidcaiMoneda::model()->findAll(
							[
								'condition' => 'mone_codigo_pk >= :id',
								'params' 	=> [
									':id' => $model2->mone_codigo_pk,
								],
								'order' => 'mone_codigo_pk DESC'
							]
						);
	
						if($division != null){
							// // Hace la multiplicación para saber entre cuanto se tiene que dividir el monto.
							for($i = 0; $i < (count($division) - 1); $i++){
								$dividir = $dividir * $division[$i]['mone_division'];
								/* var_dump($dividir); */
							}
						}
					}
	
					$devolver = $monto / $dividir;
					/* var_dump('q');
					var_dump($monto);
					var_dump($devolver);
					echo "<br>";
					echo "<br>"; */
				}		
			}else{
				if($no_reconversion){
					$devolver = $monto;
				}
			}
		}


	
		return $devolver;
	}


	/**
	 * Obtiene el valor de la Unidad Tributaria.
	 * Resta 1 año a la fecha de inicio de declaración para poder agarrar varios registro y obtener la fecha que tenga más de 183 días de vigencia.
	 */
	public static function obtenerUT(string $fecha_inicio_declaracion, string $fecha_fin_declaracion) : float{
		$fecha_inicio_declaracion = date("Y-m-d", strtotime($fecha_inicio_declaracion." -1 year"));
		
		/*$criteria = new CDbCriteria;
		$criteria->condition = 'unid_habilitado = true';
		$criteria->addBetweenCondition('unid_fechacomienzo', $fecha_inicio_declaracion, $fecha_fin_declaracion);
		$criteria->order = 'unid_codigo_pk DESC';*/

		$criteria = new CDbCriteria;
		$criteria->condition = 'unid_habilitado = true and (unid_fechacomienzo between to_date(:fechaInicio,\'YYYY-MM-DD\') and to_date(:fechaFin,\'YYYY-MM-DD\'))';
		$criteria->params = array(':fechaInicio' => $fecha_inicio_declaracion, ':fechaFin' => $fecha_fin_declaracion);
		$criteria->order = 'unid_fechacomienzo DESC';
		$unidad_tributaria = SidcaiUnidadtributaria::model()->findAll($criteria);
		//print_r($unidad_tributaria);die();
		
        
		$UT		  = NULL;
		$valor_UT = 0;

		if($unidad_tributaria != NULL){
			// Se suman los 183 dias a las fecha de comienzo, y aquella fecha que no supere la fecha de fin es el registro correcto.
			foreach($unidad_tributaria as $uni){
				$fecha_inicio_sumada = date("Y-m-d",strtotime($uni->unid_fechacomienzo." +183 day")); 

				if(strtotime($fecha_inicio_sumada) < strtotime($fecha_fin_declaracion)){
					$valor_UT = $uni->unid_valor;
					break;
				}			
			}
		}else{
			$unidad_tributaria = SidcaiUnidadtributaria::model()->find(
				array(
					'limit' => 1,
					'order' => 'unid_codigo_pk DESC'
				)
			);

			$valor_UT = $unidad_tributaria->unid_valor;
		}


		if($valor_UT == 1200){
			if(strtotime($fecha_fin_declaracion) > strtotime("2018-08-20"))
				$valor_UT = $valor_UT / 100000;
		}

		return $valor_UT;
	}

	/****** En caso de que se quiera mostrar los errores de cada input, solo muestra un error a la vez. *******/
	public static function erroresModel($model, string $nombre_model) : string{
		$errores = "";
		
		foreach($model->errors as $key => $error){
			if(array_key_exists($key, $nombre_model::attributeLabels()))
				return "<b>".$nombre_model::attributeLabels()[$key]."</b>: ".$error[0];
		}

		return $errores;
	}

	/**
	 * Obtiene la cantidad de días que tiene el año solicitado
	 * Devuelve => 365 o 366
	 * Usada para sacar el Factor en los intereses moratorios
	 */
	public static function cal_days_in_year(string $year) : int{
	    $days = 0; 

	    for($month = 1; $month <= 12; $month++){ 
	    	$days = $days + cal_days_in_month(CAL_GREGORIAN, $month, $year);
	    }

	 return $days;
	}

	/**
	 * Valor del Petro
	 */
	public static function obtenerValorPetro() : float{
		// peticiones http php json
		// Código: https://parzibyte.me/blog/2019/08/21/peticion-http-php-json-formulario/

		$url = "https://petroapp-price.petro.gob.ve/price/";

		// Los datos JSON
		/*$datos = [
		    "coins" => ["PTR", "BTC"],
		    "fiats" => ["USD", "EUR", "RUB", "CNY", "BS"],
		];*/
		/*$datos = [
		    "coins" => ["PTR"],
		    "fiats" => ["BS"],
		];

		// Crear opciones de la petición HTTP
		$opciones = array(
		    "http" => array(
		        "header" => "Content-Type:application/json",
		        "method" => "POST",
		        "content" => json_encode($datos), # Agregar el contenido definido antes
		    ),
		);
		# Preparar petición
		$contexto = stream_context_create($opciones);
		# Hacerla
		$resultado = file_get_contents($url, false, $contexto);
		if($resultado === false){
		    return "Error en petición.";
		}

		# si no salimos allá arriba, todo va bien
		$resultado = json_decode($resultado);
		$valor_petro = $resultado->data->PTR->BS;*/
		$valor_petro = 35771706.47;

		return $valor_petro;
	}

	/**
	 * Obtener el resultado de una función sin redondear.
	 * Máximo hasta la cifra en $number "214748"
	 */
	public static function truncateFloat($number, $digitos){
	    $raiz = 10;
	    $multiplicador = pow ($raiz,$digitos);
	    $resultado = ((int)($number * $multiplicador)) / $multiplicador;
	    return number_format($resultado, $digitos, '.', '');
	}

	/**
	 * Permite a los perfiles enviados en el array acceder al contenido.
	 */
	public static function permitirPerfil(array $perfiles) : bool{
		$cantidad = count($perfiles);
		$existe = false;
		if($cantidad > 0){
			for($i = 0; $i < $cantidad; $i++){
				if(in_array($perfiles[$i], Yii::app()->user->getState("perfiles"))){	
					$existe = true;
					break;
				}
			}
		}

		return $existe;
	}


	/**
	 * Crea código QR.
	 */
	public static function crearQR(string $mensaje, $destino = null, $correcion, $tamano = 2, $padding = 2){
		require_once(Yii::app()->basePath . '/extensions/phpqrcode/qrlib.php');

		$qr_ec_level = QR_ECLEVEL_L;

		switch ($correcion) {
			case 'L':
				$qr_ec_level = QR_ECLEVEL_L;
				break;
			case 'M':
				$qr_ec_level = QR_ECLEVEL_M;
				break;
			case 'Q':
				$qr_ec_level = QR_ECLEVEL_Q;
				break;
			case 'H':
				$qr_ec_level = QR_ECLEVEL_H;
				break;
		}

		ob_start();
		QRCode::png($mensaje, $destino, $qr_ec_level, $tamano, $padding);
		$imageString = base64_encode( ob_get_contents() );
		ob_end_clean();

		return $imageString;
	}

	/**
	 * Verifica si la empresa tiene intereses moratorios y en caso de tenerlos devuelve el monto que le corresponde a sus interes moratorios.
	 */
	public static function obtenerInteresesMoratorios($declaracion, $array_declaraciones, $fecha_ultimo_pago = false, $para_intereses = false) : float{
		// Se importa el controlador para hacer uso del método "cal_days_in_year".

		$date = new DateTime("now", new DateTimeZone('America/Caracas'));

		$hoy = $date->format('Y-m-d');

		$anio = $date->format("Y");
		$dia  = $date->format('d');
		// Se obtiene los datos de la declaración a saber los intereses moratorios.
		$declaracion = SidcaiDeclaracioncti::model()->findByPk($declaracion);
		// Se busca la última declaración del array (puede exitir el caso de que tenga más de una declaración).
		$id_ultima_declaracion = $array_declaraciones[(count($array_declaraciones) - 1)];
		$ultima_declaracion = SidcaiDeclaracioncti::model()->findByPk($id_ultima_declaracion);

		// Se le da al Aportante 15 días para que pague sus Intereses Moratorios, de lo contrario tendrá un nuevo monto.
		if(count($array_declaraciones) > 1){
			$dias15 = date("Y-m-d", strtotime($ultima_declaracion->decl_fechadeclaracion."+ ".self::diasAfiscalizacion()." day"));
		}else{
			// Cuando solo tiene una sola declaración y pasó su fecha a declarar y pagar.
			$dias15 = date("Y-m-d", strtotime($ultima_declaracion->decl_fechadeclaracion."+ ".self::diasAfiscalizacion(true)." day"));
		}

		if(strtotime($hoy) <= strtotime($dias15) || $para_intereses){
			$hoy  = $ultima_declaracion->decl_fechadeclaracion;
			$fec  = explode("-", $declaracion->decl_fechadeclaracion);
			$dia  = $fec[2];
			$anio = $fec[0];
		}

		if($fecha_ultimo_pago){
			$array_declaraciones_string = implode(",", $array_declaraciones);
			// Se busca la fecha del último pago.
			$ultimo_pago = SidcaiDeclaracionDetalle::model()->find([
				'condition' => 'codigo_declaraciones = :codigo_declaraciones AND apor_codigo_fk = :apor_codigo_fk',
				'params' => [
					':codigo_declaraciones' => $array_declaraciones_string,
					':apor_codigo_fk' => $ultima_declaracion->apor_codigo_fk,
				],
				'order' => 'deta_codigo_pk DESC'
			]);


			if($ultimo_pago != null){
				$hoy  = $ultimo_pago->decl_fechapago;
				$fec  = explode("-", $ultimo_pago->decl_fechapago);
				$dia  = $fec[2];
				$anio = $fec[0];
			}
		}


		$fecha_inicio 		= $declaracion->decl_fechafin;
		// Se suma un día de su fecha fin para comenzar a calcular los intereses.
		$dia_desde_sumar 	= date("Y-m-d", strtotime($fecha_inicio."+1 day"));
		$fecha_inicio 		= $dia_desde_sumar;
		$fecha_inicio_array = explode("-", $fecha_inicio);

		$fecha_fin_array = explode('-', $hoy);

		$datetime1 = new DateTime($fecha_inicio, new DateTimeZone('America/Caracas'));
		$datetime2 = new DateTime($hoy, new DateTimeZone('America/Caracas'));

		# obtenemos la diferencia entre las dos fechas
		$interval = $datetime2->diff($datetime1);

		# obtenemos la diferencia en meses
		$intervalMeses = $interval->format("%m");
		# obtenemos la diferencia en años y la multiplicamos por 12 para tener los meses
		$intervalAnos = $interval->format("%y")*12;

		$meses = $intervalMeses + $intervalAnos;


		// Obtiene desde que mes se va a obtener los intereses
		if($fecha_inicio_array[1] > 9){
		    $desde_mes = $fecha_inicio_array[1]; 
		}else{
		    $desde_mes = ($fecha_inicio_array[1] / 10 * 10);
		}

		$contador = 0;
		$anio = $fecha_inicio_array[0];
		$mes = $desde_mes;

		$dia = $fecha_inicio_array[2];

		$connection = Yii::app()->db;

		$no_reconversion = ($para_intereses) ? true : false;

		$deuda = self::reconversion($declaracion->decl_fechadeclaracion, $declaracion->decl_montorequerido, $no_reconversion);

		$intereses_moratorios = 0.00;

		for($i = $desde_mes; $i <= ($meses + $desde_mes); $i++){
		    if($mes > 12){
		        $mes = 1;
		        $anio++;
		    }

		    if($mes < 10)
		        $mes = "0$mes"; 


		    $fecha = "$anio-$mes-01";

		    // Se obtiene cuantos días hay en el mes.
		    $dias_en_mes = date('t', strtotime($fecha));

		    $sql = "SELECT tasa_interes FROM sidcai_tasainteres WHERE :fecha >= tasa_fechainicio AND :fecha <= (CASE WHEN tasa_fechafin != null THEN tasa_fechafin ELSE '2099-12-31' END) ORDER BY tasa_codigo_pk DESC LIMIT 1";
		    $command = $connection->createCommand();
		    $command->text = $sql;
		    $command->bindParam(':fecha', $fecha);
		    $model = $command->queryRow();

		    $dias_en_anio = self::cal_days_in_year($anio);

		    $fecha = "$anio-$mes-$dias_en_mes";


		    $tasa_interes       = $model['tasa_interes'];
		    $tasa_incrementada  = $tasa_interes * 1.2;
		    // $tasa_incrementada  = self::truncateFloat($tasa_incrementada, 4);
		    // $factor             = self::truncateFloat(($tasa_incrementada / 100 / 365), 11);
		    $tasa_incrementada  = bcdiv($tasa_incrementada, '1', 4);
		    $factor 			= bcdiv(($tasa_incrementada / 100 / 365), '1', 4);

		    $dia_factor = ($i == ($meses + $desde_mes)) ? $fecha_fin_array[2] : $dias_en_mes;

		    $resultado = $factor * $deuda * $dia_factor;
		    $intereses_moratorios += $resultado;
		    $mes++;
		}

		return bcdiv(self::reconversion($declaracion->decl_fechadeclaracion, $intereses_moratorios, $no_reconversion), '1', 2);
	}

	/**
	 * Devuelve el monto de la Multa Material
	 */
	public static function obtenerMultaMaterial(float $monto_requerido) : float{
		$multa_material = $monto_requerido / 2;

		return bcdiv($multa_material, '1', 2);
	}

	/**
	 * Obtiene los intereses moratorios desde el area de fiscalización.
	 */
	public static function obtenerInteresesMoratoriosMultaFormal(int $declaracion, array $array_declaraciones, array $array_declaraciones_multa, bool $para_intereses = false) : float{
		$date = new DateTime("now", new DateTimeZone('America/Caracas'));

		$hoy = $date->format('Y-m-d');

		$anio = $date->format("Y");
		$dia  = $date->format('d');
		// Se obtiene los datos de la declaración a saber los intereses moratorios.
		$declaracion = SidcaiDeclaracioncti::model()->findByPk($declaracion);
		// Se busca la última declaración del array (puede exitir el caso de que tenga más de una declaración).
		$id_ultima_declaracion = max($array_declaraciones);
		$ultima_declaracion = SidcaiDeclaracioncti::model()->findByPk($id_ultima_declaracion);

		// Se busca el último pago de la multa formal para dar 15 días que se van a congelar.
		$multa_colocada = SidcaiDeclaracionMulta::model()->find([
			'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_codigo_fk != :mult_codigo_fk AND mult_habilitada = :mult_habilitada',
			'params' => [
				':decl_codigo_fk' => max($array_declaraciones_multa),
				':mult_codigo_fk' => 1,
				':mult_habilitada' => TRUE
			]
		]);

		if($multa_colocada != null){
			// Se le da al Aportante 15 días para que pague sus Intereses Moratorios, de lo contrario tendrá un nuevo monto.
			$dias15 = date("Y-m-d", strtotime($multa_colocada->decl_mult_fecha."+15 day"));

			if(strtotime($hoy) <= strtotime($dias15) || $para_intereses){
				$hoy  = $multa_colocada->decl_mult_fecha;
			}
		}


		$fecha_inicio 		= $declaracion->decl_fechafin;
		// Se suma un día de su fecha fin para comenzar a calcular los intereses.
		$dia_desde_sumar 	= date("Y-m-d", strtotime($fecha_inicio."+1 day"));
		$fecha_inicio 		= $dia_desde_sumar;
		$fecha_inicio_array = explode("-", $fecha_inicio);

		$fecha_fin_array = explode('-', $hoy);

		$datetime1 = new DateTime($fecha_inicio, new DateTimeZone('America/Caracas'));
		$datetime2 = new DateTime($hoy, new DateTimeZone('America/Caracas'));

		# obtenemos la diferencia entre las dos fechas
		$interval = $datetime2->diff($datetime1);

		# obtenemos la diferencia en meses
		$intervalMeses = $interval->format("%m");
		# obtenemos la diferencia en años y la multiplicamos por 12 para tener los meses
		$intervalAnos = $interval->format("%y")*12;

		$meses = $intervalMeses + $intervalAnos;


		// Obtiene desde que mes se va a obtener los intereses
		if($fecha_inicio_array[1] > 9){
		    $desde_mes = $fecha_inicio_array[1]; 
		}else{
		    $desde_mes = ($fecha_inicio_array[1] / 10 * 10);
		}

		$contador = 0;
		$anio = $fecha_inicio_array[0];
		$mes = $desde_mes;

		$dia = $fecha_inicio_array[2];

		$connection = Yii::app()->db;
		$deuda = self::reconversion($declaracion->decl_fechadeclaracion, $declaracion->decl_montorequerido);

		$intereses_moratorios = 0.00;

		for($i = $desde_mes; $i <= ($meses + $desde_mes); $i++){
		    if($mes > 12){
		        $mes = 1;
		        $anio++;
		    }

		    if($mes < 10)
		        $mes = "0$mes"; 

		    $fecha = "$anio-$mes-01";

		    // Se obtiene cuantos días hay en el mes.
		    $dias_en_mes = date('t', strtotime($fecha));

		    $sql = "SELECT tasa_interes FROM sidcai_tasainteres WHERE :fecha >= tasa_fechainicio AND :fecha <= (CASE WHEN tasa_fechafin != null THEN tasa_fechafin ELSE '2099-12-31' END) ORDER BY tasa_codigo_pk DESC LIMIT 1";
		    $command = $connection->createCommand();
		    $command->text = $sql;
		    $command->bindParam(':fecha', $fecha);
		    $model = $command->queryRow();

		    $dias_en_anio = self::cal_days_in_year($anio);

		    $fecha = "$anio-$mes-$dias_en_mes";

		    $tasa_interes       = $model['tasa_interes'];
		    $tasa_incrementada  = $tasa_interes * 1.2;
		    $tasa_incrementada  = bcdiv($tasa_incrementada, '1', 4);
		    $factor 			= bcdiv(($tasa_incrementada / 100 / 365), '1', 4);

		    $dia_factor = ($i == ($meses + $desde_mes)) ? $fecha_fin_array[2] : $dia_factor = $dias_en_mes;

		    $resultado = $factor * $deuda * $dia_factor;
		    $intereses_moratorios += $resultado;
		    $mes++;
		}

		return bcdiv($intereses_moratorios, '1', 2);
	}

	/**
	 * Obtiene el fin del periodo gravable.
	 */
	public static function obtenerFinPeriodoGravable(string $inicio_periodo_grvable) : string{
		$fecha_fin_declarar =  new DateTime($inicio_periodo_grvable);;
		$fecha_fin_declarar = self::addYears($fecha_fin_declarar, +1);
		$fecha_fin_declarar = $fecha_fin_declarar->format('Y-m-d');
		return  date('Y-m-d', strtotime($fecha_fin_declarar."-1 day"));
	}

	/**
	 * Obtiene los periodos a declarar y pagar de la declaración.
	 */
	public static function obtenerPeriodosDeclarar(string $fin_periodo_gravable) : array{
		$fin_periodo_gravable = self::convertirFecha($fin_periodo_gravable, "yyyy-mm-dd");

		$fecha_inicio_declarar =  new DateTime($fin_periodo_gravable);
		$fecha_inicio_declarar = self::addMonths($fecha_inicio_declarar, +3);
		$fecha_inicio_declarar = $fecha_inicio_declarar->format('Y-m-d');
		$fecha_inicio_declarar = date('Y-m-d', strtotime($fecha_inicio_declarar."+1 day"));

		$fecha_fin_declarar =  new DateTime($fecha_inicio_declarar);
		$fecha_fin_declarar = self::addMonths($fecha_fin_declarar, +3);
		$fecha_fin_declarar = $fecha_fin_declarar->format('Y-m-d');
		$fecha_fin_declarar = date('Y-m-d', strtotime($fecha_fin_declarar."-1 day"));

		return [
			'fecha_inicio_declarar' => $fecha_inicio_declarar,
			'fecha_fin_declarar' => $fecha_fin_declarar,
		];
	}

	/**
	 * Agrega un mes a la fecha de forma mas precisa.
	 * Código: https://www.php.net/manual/es/datetime.modify.php
	 */	
	public static function addMonths($date, $months){
	    $years = floor(abs($months / 12));
	    $leap = 29 <= $date->format('d');
	    $m = 12 * (0 <= $months?1:-1);
	    for ($a = 1;$a < $years;++$a) {
	        $date = addMonths($date, $m);
	    }
	    $months -= ($a - 1) * $m;
	   
	    $init = clone $date;
	    if (0 != $months) {
	        $modifier = $months . ' months';
	       
	        $date->modify($modifier);
	        if ($date->format('m') % 12 != (12 + $months + $init->format('m')) % 12) {
	            $day = $date->format('d');
	            $init->modify("-{$day} days");
	        }
	        $init->modify($modifier);
	    }
	   
	    $y = $init->format('Y');
	    if ($leap && ($y % 4) == 0 && ($y % 100) != 0 && 28 == $init->format('d')) {
	        $init->modify('+1 day');
	    }
	    return $init;
	}

	/**
	 * Agrega un año a la fecha de forma mas precisa.
	 * Código: https://www.php.net/manual/es/datetime.modify.php
	 */	
	public static function addYears($date, $years){
	    return self::addMonths($date, 12 * $years);
	}

	public static function cifras_en_letras($numero, $con_centimos = true){
		Yii::import('application.vendors.cifras_en_letras.CifrasEnLetras');

		$concatenar = "";

		if($con_centimos){		
			$centimos = explode(".", $numero);

			$concatenar = " céntimos";

			if(isset($centimos[1])){
				if($centimos[1] == 0.00){
					$concatenar = " sin céntimos";
				}
			}
		}

		return CifrasEnLetras::convertirNumeroEnLetras($numero).$concatenar;
	}

	/**
	 * Muestra las declaraciones en Verificar Pago.
	 */
	public static function mostrarDeclaracionesVerificarPago(array $declaraciones) : string{
		$tabla = "";

		if($declaraciones != null){
			for($i = 0; $i < count($declaraciones); $i++){
				$declaracion = SidcaiDeclaracioncti::model()->findByPk($declaraciones[$i]);

				$tabla .= "<tr>";
				$tabla .= "<td>$declaracion->decl_codigo_pk</td>";

				$fecha_declaracion = self::convertirFecha($declaracion->decl_fechadeclaracion, "dd/mm/yyyy");

				$tabla .= "<td>$fecha_declaracion</td>";
				$tabla .= "<td>".$declaracion->estaCodigoFk->esta_nombre."</td>";

				$ejercicio_economico = self::convertirFecha($declaracion->decl_fechainicio_base, "dd/mm/yyyy");
				$ejercicio_economico .= " " .self::convertirFecha($declaracion->decl_fechafin_base, "dd/mm/yyyy");

				$tabla .= "<td>$ejercicio_economico</td>";

				$tabla .= "<td>";
				$tabla .= "<button style='padding: 8px' type='button' class='btn btn-info' data-toggle='modal' data-target='#modalDeclaracion' title='Ver declaración' onclick='mostrarDeclaracion(".$declaracion->decl_codigo_pk.", $declaracion->apor_codigo_fk)' id='" .$declaracion->decl_codigo_pk. "'><i class='material-icons'>visibility</i></button>";

				if(strtotime($declaracion->decl_fechadeclaracion) > strtotime($declaracion->decl_fechafin)){				
					$tabla .= TbHtml::linkButton('<span class="material-icons">picture_as_pdf</span>', [
						'url' => Yii::app()->baseUrl.'/declaracion/acta_reparo/'.$declaracion->decl_codigo_pk,
						'class' => 'btn btn-danger btn-sm',
						'style' => 'padding: 8px',
						'target' => '_blank'
					]);
				}

				$tabla .= "</td>";
				$tabla .= "</tr>";
			}			
		}

		if($tabla == ""){
			$tabla = "<tr><td colspan='5'>No hay declaraciones</td></tr>";
		}

		return $tabla;
	}

	/**
	 * Muestra todas las declaraciones que tiene la empresa en las 2 base de datos.
	 */
	public static function mostrarDeclaraciones(array $declaraciones, string $rif) : string{
		$tabla = "";
		$tabla_historico = "";

		$rif_empresa = $rif;

		$sql = "SELECT apor_codigo_pk FROM sidcai_aportante WHERE apor_rif = :apor_rif AND esta_codigoestatus_fk = 2003";
		$comando = Yii::app()->db2->createCommand($sql);
		$comando->bindParam(":apor_rif", $rif_empresa);
		$empresa_historico = $comando->queryRow();
			
		$sql = "SELECT * FROM sidcai_declaracioncti WHERE apor_codigo_fk = :apor_codigo_fk ORDER BY decl_codigo_pk DESC";
		$comando = Yii::app()->db2->createCommand($sql);
		$comando->bindParam(':apor_codigo_fk', $empresa_historico['apor_codigo_pk']);
		$dcl = $comando->queryAll();

		if($dcl != null){
			foreach($dcl as $declaracion){
				$tabla_historico .= "<tr>";
				$tabla_historico .=  "<td><a target='_blank' href='".Yii::app()->baseUrl."/analista/declaracion/".$declaracion['decl_codigo_pk']."'>".$declaracion['decl_codigo_pk']."</a></td>";

				$fecha_declaracion = self::convertirFecha($declaracion['decl_fechadeclaracion'], "dd/mm/yyyy");

				$tabla_historico .= "<td>".$fecha_declaracion."</td>";

				$ejercicio_economico = self::convertirFecha($declaracion['decl_fechainicio_base'], "dd/mm/yyyy");
				$ejercicio_economico .= " " .self::convertirFecha($declaracion['decl_fechafin_base'], "dd/mm/yyyy");
				$tabla_historico .= "<td>".$ejercicio_economico."</td>";

				$estatus = SidcaiEstatus::model()->findByPk($declaracion['esta_codigo_fk']);
				$tabla_historico .= "<td>" .$estatus->esta_nombre. "</td>";

				$tabla_historico .= "<td>";
				$tabla_historico .= "<button style='padding: 8px' type='button' class='btn btn-info' data-toggle='modal' data-target='#modalDeclaracion' title='Ver declaración' onclick='mostrarDeclaracion(".$declaracion['decl_codigo_pk'].", ".$declaracion['apor_codigo_fk'].")' id='" .$declaracion['decl_codigo_pk']. "'><i class='material-icons'>visibility</i></button>";

				$tabla_historico .= "</td>";

				$tabla_historico .= "</td>";
				$tabla_historico .= "</tr>";
			}
		}

		if($declaraciones != null){
			for($i = 0; $i < count($declaraciones); $i++){
				$declaracion = SidcaiDeclaracioncti::model()->findByPk($declaraciones[$i]);

				$tabla .= "<tr>";
				$tabla .= "<td><a target='_blank' href='".Yii::app()->baseUrl."/analista/declaracion/".$declaracion->decl_codigo_pk."'>".$declaracion->decl_codigo_pk."</a></td>";

				$fecha_declaracion = self::convertirFecha($declaracion->decl_fechadeclaracion, "dd/mm/yyyy");

				$tabla .= "<td>$fecha_declaracion</td>";

				$ejercicio_economico = self::convertirFecha($declaracion->decl_fechainicio_base, "dd/mm/yyyy");
				$ejercicio_economico .= " " .self::convertirFecha($declaracion->decl_fechafin_base, "dd/mm/yyyy");

				$tabla .= "<td>$ejercicio_economico</td>";
				
				$tabla .= "<td>".$declaracion->estaCodigoFk->esta_nombre."</td>";

				$tabla .= "<td>";
				$tabla .= "<button style='padding: 8px' type='button' class='btn btn-info' data-toggle='modal' data-target='#modalDeclaracion' title='Ver declaración' onclick='mostrarDeclaracion(".$declaracion->decl_codigo_pk.", $declaracion->apor_codigo_fk)' id='" .$declaracion->decl_codigo_pk. "'><i class='material-icons'>visibility</i></button>";

				$fecha_fin = date("Y-m-d",strtotime($declaracion->decl_fechafin." +".$declaracion->decl_dias_prorroga." day"));

				// Se busca si la declaración tiene otras relacionadas
				$tiene_relacionadas = SidcaiDeclaracionRelacionada::model()->find([
					'condition' => 'decl_codigo_fk = :decl_codigo_fk OR decl_atrasada_fk = :decl_atrasada_fk',
					'params' => [
						':decl_codigo_fk' => $declaraciones[$i],
						':decl_atrasada_fk' => $declaraciones[$i],
					]
				]);

				if(strtotime($declaracion->decl_fechadeclaracion) > strtotime(date('Y-m-d', strtotime($fecha_fin."+".$declaracion->decl_dias_prorroga." day"))) || $tiene_relacionadas != null){				
					$tabla .= TbHtml::linkButton('<span class="material-icons">picture_as_pdf</span>', [
						'url' => Yii::app()->baseUrl.'/declaracion/acta_reparo/'.$declaracion->decl_codigo_pk,
						'class' => 'btn btn-danger btn-sm',
						'style' => 'padding: 8px',
						'target' => '_blank'
					]);

					$id = $declaracion->decl_codigo_pk;

					if($tiene_relacionadas != null){
						$id = $tiene_relacionadas->decl_codigo_fk;
					}

					// Se busca multa formal
					$multa_formal = SidcaiDeclaracionMulta::model()->find([
						'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_codigo_fk != :mult_codigo_fk AND mult_habilitada = :mult_habilitada',
						'params' => [
							':decl_codigo_fk' => $id,
							':mult_codigo_fk' => 1,
							':mult_habilitada' => TRUE
						]
					]);

					if($multa_formal != null){
						$tabla .= TbHtml::linkButton('<span class="material-icons">picture_as_pdf</span>', [
							'url' => Yii::app()->baseUrl.'/declaracion/acta_reparo_deberes_formales/'.$declaracion->decl_codigo_pk,
							'class' => 'btn btn-danger btn-sm',
							'style' => 'padding: 8px',
							'target' => '_blank'
						]);
					}
				}

				$tabla .= "</td>";
				$tabla .= "</tr>";
			}			
		}

		if($tabla == "" && $tabla_historico == ""){
			$tabla = "<tr><td colspan='5'>No hay declaraciones</td></tr>";
		}

		return $tabla.$tabla_historico;
	}


	/**
	 * Datos del Google Recaptcha V3
	 */
	public static function reCaptcha(string $token) {
		$secret = Yii::app()->params['recaptcha_key_secret'];
		$token = CHtml::encode($token);
		$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$token");
		$response = json_decode($response);
		return $response;
	}


	/**
	 * En caso de haber prorroga para las declaraciones
	 */
	public static function diasProrroga(string $fecha_fin) : int{
		$parametro = SidcaiParametro::model()->find();

		$date = new DateTime("now", new DateTimeZone('America/Caracas'));
		$hoy = $date->format('Y-m-d');

		$dias = 0;

		if(strtotime($hoy) <= strtotime($parametro->para_fecha_tope_prorroga)){
			if(strtotime($fecha_fin) < strtotime($parametro->para_fecha_tope_prorroga)){			
				$date1 = new DateTime($fecha_fin);
				$date2 = new DateTime($parametro->para_fecha_tope_prorroga);
				$diff = $date1->diff($date2);
				$dias = $diff->days;
			}
		}

		return $dias;
	}

	/**
	 * Cantidad de días que tienen que transcurrir para que la declaración sea enviada a fiscalización
	 * $una_declaracion => Sí es TRUE es que solo es cuando la empresa no está pagando con declaraciones atrasadas/relacionadas
	 */
	public static function diasAfiscalizacion($una_declaracion = false) : string{
		return "15";
	}


	/**
	 * Detalles de la declaración
	 * @return array
	 */
	public static function detallesDeclaracion(int $id_declaracion, string $codigo_declaraciones) : string{
		
		//print_r($codigo_declaraciones);die();
		
		/*$detalle_declaracion = SidcaiDeclaracionDetalle::model()->findAll([
			'condition' => 'codigo_declaraciones = :codigo_declaraciones',
			'params' => [':codigo_declaraciones' => $codigo_declaraciones],
			'order' => 'deta_codigo_pk DESC'
		]);*/

		$detalle_declaracion = SidcaiDeclaracionDetalle::model()->findAll([
			'condition' => 'codigo_declaraciones LIKE :codigo_declaraciones',
			'params' => [':codigo_declaraciones' => '%' . $codigo_declaraciones . '%'],
			'order' => 'deta_codigo_pk DESC'
		]);
		

		//print_r($detalle_declaracion);die();

		$tabla = "";

		if($detalle_declaracion != null){
			$declaracion = SidcaiDeclaracioncti::model()->findByPk($id_declaracion);
			

			foreach($detalle_declaracion as $d){
				$monto_detalle = FuncionesController::obtenerMoneda($d->decl_fechapago)." ".number_format($d->decl_monto, 2, ',', '.');

				// Fecha de pago
				$fecha_pago = FuncionesController::convertirFecha($d->decl_fechapago, "dd/mm/yyyy");

				// Fecha de registro del pago
				$fecha_registro = FuncionesController::convertirFecha($d->fecha_registro, "dd/mm/yyyy");

				// Modalidad
				$modalidad_pago = ($d->decl_modalidadpago == 2) ? 'Transferencia' : 'Desconocido';

				// Numero de cuenta bancaria con tooltip
				$cuenta = SidcaiBanco::model()->findByPk($d->banc_codigo_fk);
				$tooltip_banco = "<span data-tooltip='".$cuenta->banc_nombre."'>".$cuenta->banc_ruta."</span>";

				// Motivo de Rechazo
				$motivo_rechazo = "";
				if($d->rech_codigo_fk !== NULL){
					$m_rechazo = SidcaiRechazarPago::model()->findByPk($d->rech_codigo_fk);
					$motivo_rechazo = $m_rechazo->rech_descripcion;
				}

				$moneda = FuncionesController::obtenerMoneda($d->decl_fechapago);
				$monto  = $moneda." ".number_format($d->decl_monto, 2, ",", ".");

				if($d->analista_fk !== null)
					$analista_tooltip = "<span data-tooltip='".$d->analistaFk->usua_nombre." ".$d->analistaFk->usua_apellido."'>".$d->analistaFk->usua_documento."</span>";
				else
					$analista_tooltip = "";

				$usuario_auditor_tooltip = "N/A";

				if($d->audit_usua !== NULL)
					$usuario_auditor_tooltip = "<span data-tooltip='".$d->auditUsua->usua_nombre." ".$d->auditUsua->usua_apellido."'>".$d->auditUsua->usua_documento."</span>";


				if($d->decl_pago_aceptado === NULL)
					$estatus_pago = "<span class='text-dark font-weight-bold'>n/a</span>";
				else if($d->decl_pago_aceptado == FALSE)
					$estatus_pago = "<span class='text-danger font-weight-bold'>Rechazado</span>";
				else
					$estatus_pago = "<span class='text-success font-weight-bold'>Aceptado</span>";	


				$tabla .= '  
					<div class="card m-5">
					<div class="card-body">
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">ID:</b> '.$d->deta_codigo_pk.'
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Fecha de Pago:</b> '.$fecha_pago.'
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Modalidad:</b> '.$modalidad_pago.' 
					</div>
					</div>
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Banco:</b> '.$tooltip_banco.'
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Referencia:</b> '.$d->decl_referencia.' 
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Monto:</b> '.$monto.' 
					</div>
					</div>
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Analista:</b> '.$analista_tooltip.'
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Auditor:</b> '.$usuario_auditor_tooltip.' 
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Alicuota:</b> '.$declaracion->decl_alicuota.' % 
					</div>
					</div>
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Estatus:</b> '.$estatus_pago.'
					</div>
					<div class="col-12 col-sm-8">
					<b class="text-black-secondary">Motivo:</b> '.$motivo_rechazo.' 
					</div>
					</div>
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Fecha Registro:</b> '.$fecha_registro.'
					</div>
					<div class="col-12 col-sm-4">
					</div>
					<div class="col-12 col-sm-4">
					<button style="padding: 10px" type="button" class="btn btn-warning" data-toggle="modal" data-target="#modalComprobante" title="Ver comprobante" onclick="comprobante('.$d->deta_codigo_pk.', 1)"><i class="fas fa-file-invoice"></i> comprobante</button>
					</div>
					</div>
				';

				$tabla .= '  
				   </div>
				   </div>
				';
			}			
		}else{
			$tabla = "<div class='text-center m5'>No hay datos.</div>";
		}
		
		return $tabla;
	}


	/**
	 * Comprobantes de la declaración TESORERIA
	 * @return array
	 */
	public static function comprobantesDeclaracionTesoreria(int $id_declaracion, string $codigo_declaraciones) : string{
		$detalle_declaracion = SidcaiDeclaracionDetalle::model()->findAll([
			'condition' => 'codigo_declaraciones = :codigo_declaraciones',
			'params' => [':codigo_declaraciones' => $codigo_declaraciones],
			'order' => 'deta_codigo_pk DESC'
		]);

		$tabla = "";

		if($detalle_declaracion != null){
			$declaracion = SidcaiDeclaracioncti::model()->findByPk($id_declaracion);

			foreach($detalle_declaracion as $d){
				$monto_detalle = FuncionesController::obtenerMoneda($d->decl_fechapago)." ".number_format($d->decl_monto, 2, ',', '.');

				// Fecha de pago
				$fecha_pago = FuncionesController::convertirFecha($d->decl_fechapago, "dd/mm/yyyy");

				// Fecha de registro del pago
				$fecha_registro = FuncionesController::convertirFecha($d->fecha_registro, "dd/mm/yyyy");

				// Modalidad
				$modalidad_pago = ($d->decl_modalidadpago == 2) ? 'Transferencia' : 'Desconocido';

				// Numero de cuenta bancaria con tooltip
				$cuenta = SidcaiBanco::model()->findByPk($d->banc_codigo_fk);
				$tooltip_banco = "<span data-tooltip='".$cuenta->banc_nombre."'>".$cuenta->banc_ruta."</span>";

				// Motivo de Rechazo
				$motivo_rechazo = "";
				if($d->rech_codigo_fk !== NULL){
					$m_rechazo = SidcaiRechazarPago::model()->findByPk($d->rech_codigo_fk);
					$motivo_rechazo = $m_rechazo->rech_descripcion;
				}

				// Monto
				$moneda = FuncionesController::obtenerMoneda($d->decl_fechapago);
				$monto  = $moneda." ".number_format($d->decl_monto, 2, ",", ".");

				if($d->analista_fk !== null)
					$analista_tooltip = "<span data-tooltip='".$d->analistaFk->usua_nombre." ".$d->analistaFk->usua_apellido."'>".$d->analistaFk->usua_documento."</span>";
				else
					$analista_tooltip = "";

				$usuario_auditor_tooltip = "N/A";

				if($d->audit_usua !== NULL)
					$usuario_auditor_tooltip = "<span data-tooltip='".$d->auditUsua->usua_nombre." ".$d->auditUsua->usua_apellido."'>".$d->auditUsua->usua_documento."</span>";


				if($d->decl_pago_aceptado === NULL)
					$estatus_pago = "<span class='text-dark font-weight-bold'>n/a</span>";
				else if($d->decl_pago_aceptado == FALSE)
					$estatus_pago = "<span class='text-danger font-weight-bold'>Rechazado</span>";
				else
					$estatus_pago = "<span class='text-success font-weight-bold'>Aceptado</span>";	


				$tabla .= '  
					<div class="card m-5">
					<div class="card-body">
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">ID:</b> '.$d->deta_codigo_pk.'
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Fecha de Pago:</b> '.$fecha_pago.'
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Modalidad:</b> '.$modalidad_pago.' 
					</div>
					</div>
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Banco:</b> '.$tooltip_banco.'
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Referencia:</b> '.$d->decl_referencia.' 
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Monto:</b> '.$monto.' 
					</div>
					</div>
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Analista:</b> '.$analista_tooltip.'
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Auditor:</b> '.$usuario_auditor_tooltip.' 
					</div>
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Alicuota:</b> '.$declaracion->decl_alicuota.' % 
					</div>
					</div>
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Estatus:</b> '.$estatus_pago.'
					</div>
					<div class="col-12 col-sm-8">
					<b class="text-black-secondary">Motivo:</b> '.$motivo_rechazo.' 
					</div>
					</div>
				';

				$tabla .= '  
					<div class="row mb-2">
					<div class="col-12 col-sm-4">
					<b class="text-black-secondary">Fecha Registro:</b> '.$fecha_registro.'
					</div>
					<div class="col-12 col-sm-4">
					</div>
					<div class="col-12 col-sm-4">
					<button style="padding: 10px" type="button" class="btn btn-warning" data-toggle="modal" data-target="#modalComprobante" title="Ver comprobante" onclick="comprobante('.$d->deta_codigo_pk.', 1)"><i class="fas fa-file-invoice"></i> comprobante</button>
					</div>
					</div>
				';

				$tabla .= '  
				   </div>
				   </div>
				';
			}			
		}else{
			$tabla = "<div class='text-center m5'>No hay datos.</div>";
		}
		
		return $tabla;
	}



	/**
	 * Devuelve un array
	 * Array y string con las declaraciones
	 * Array y string con las declaraciones con multa
	 * Si tiene multa
	 * Array con las declaraciones (object)
	 * Cantidad de declaraciones
	 * Id de la última declaración
	 * Cantidad de pagos realizados en la declaración sin multas formales
	 * Si la útlima declaración es extemporanea.

	 * El parametro solo el id de la declaración y el id de la empresa. 
	 */
	public static function obtenerDeclaraciones(int $id_declaracion, int $id_empresa) : array{
		$date = new DateTime("now", new DateTimeZone('America/Caracas'));
		$hoy = $date->format('Y-m-d');

		$tiene_multa = false;
		$array_declaraciones 				= [];
		$array_declaraciones_multa 			= [];
		$array_declaraciones_string 		= "";
		$array_declaraciones_multa_string 	= "";
		$mensual = false;

		// Se busca primero si tiene declaraciones asociadas
		$tiene_declaraciones_asociadas = SidcaiDeclaracionRelacionada::model()->find([
			'condition' => 'decl_codigo_fk = :decl_codigo_fk OR decl_atrasada_fk = :decl_atrasada_fk',
			'params' => [
				':decl_codigo_fk' => $id_declaracion,
				':decl_atrasada_fk' => $id_declaracion,
			]
		]);
		
		if($tiene_declaraciones_asociadas != null){
			$declaraciones_asociadas = SidcaiDeclaracionRelacionada::model()->findAll([
				'condition' => 'decl_codigo_fk = :decl_codigo_fk',
				'params' => [
					':decl_codigo_fk' => $tiene_declaraciones_asociadas->decl_codigo_fk
				],
				'order' => 'decl_atrasada_fk ASC'
			]);
						
			foreach($declaraciones_asociadas as $da){
				array_push($array_declaraciones, $da->decl_atrasada_fk);
			}
			array_push($array_declaraciones, $tiene_declaraciones_asociadas->decl_codigo_fk);
		}else{
			array_push($array_declaraciones, $id_declaracion);
		}
		
		$array_declaraciones_string = implode(',', $array_declaraciones);
		//var_dump($array_declaraciones_string);
		
		$id_ultima_declaracion = max($array_declaraciones);

		// Cantidad de pagos realizados en la declaración.
		$pagos = SidcaiDeclaracionDetalle::model()->findAll([
			'condition' => 'codigo_declaraciones = :codigo_declaraciones AND apor_codigo_fk = :apor_codigo_fk AND decl_pago_aceptado = :decl_pago_aceptado',
			'params' => [
				':codigo_declaraciones' => $array_declaraciones_string,
				':apor_codigo_fk' 		=> $id_empresa,
				':decl_pago_aceptado' 	=> TRUE
			]
		]);

		$cantidad_pagos = count($pagos);

		// Si la ultima declaración es extemporanea.
		$extemporaneo = false;

		// Fecha de declaración de la última declaración.
		$fecha_declaracion_ultima = "";
		// Días de prorroga de la última declaración
		$dias_prorroga_ultima = null;

		$declaraciones = [];

		// Indica si la o las declaraciones posee un acta de recaudación.
		$posee_acta_recaudacion = true;

		$fecha_inicial = null;
		$fecha_final = null;

		for($i = 0; $i < count($array_declaraciones); $i++){
			
			$decl = SidcaiDeclaracioncti::model()->findByPk($array_declaraciones[$i]);

			if($decl->decl_montorequerido > 0.00 && (strtotime($hoy) > strtotime(date('Y-m-d', strtotime($decl->decl_fechafin."+".$decl->decl_dias_prorroga." day"))))){

				$consultar = false;

				if($id_ultima_declaracion == $decl->decl_codigo_pk){
					if($decl->esta_codigo_fk == 1003){
						// Es para cuando se está consultando y no agarre que la declaración que ya finalizó como exitosa la agarre como extemporanea.
						$consultar = true;
					}

					$extemporaneo = true;

					if($pagos != null){

						if(($pagos[($cantidad_pagos - 1)]->decl_pago_aceptado == TRUE) && (strtotime($pagos[($cantidad_pagos - 1)]->decl_fechapago) <= strtotime(date('Y-m-d', strtotime($decl->decl_fechafin."+".$decl->decl_dias_prorroga." day")))))
							$posee_acta_recaudacion = false;
					}
				}

				if($consultar == false){
					array_push($array_declaraciones_multa, $decl->decl_codigo_pk);
				}
			}

			if($decl->decl_tipodeclaracion == 'M') {
				$mensual = true;
			}

			array_push($declaraciones, $decl);

			if($fecha_inicial == null OR strtotime($fecha_inicial) > strtotime($decl->decl_fechainicio)) {
				$fecha_inicial = $decl->decl_fechainicio_base;
			}

			if($fecha_final == null OR strtotime($fecha_final) < strtotime($decl->decl_fechafin)) {
				$fecha_final = $decl->decl_fechafin_base;
			}
		}

		if($array_declaraciones_multa != null){
			$tiene_multa = true;
			$array_declaraciones_multa_string = implode(",", $array_declaraciones_multa);
		}		


		// Verifica si tiene multa formal
		$tiene_multa_formal = false;

		for($i = 0; $i < count($array_declaraciones_multa); $i++){
			$verificando_multa_formal = SidcaiDeclaracionMulta::model()->find([
				'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_codigo_fk != :mult_codigo_fk AND mult_habilitada = :mult_habilitada',
				'params' => [
					':decl_codigo_fk' => $array_declaraciones_multa[$i],
					':mult_codigo_fk' => 1,
					':mult_habilitada' => TRUE
				]
			]);

			if($verificando_multa_formal != null){
				$tiene_multa_formal = true;
				break;
			}
		}

		return [
			'tiene_multa' 						=> $tiene_multa,
			'array_declaraciones' 				=> $array_declaraciones,
			'array_declaraciones_string' 		=> $array_declaraciones_string,
			'array_declaraciones_multa' 		=> $array_declaraciones_multa,
			'array_declaraciones_multa_string' 	=> $array_declaraciones_multa_string,
			'declaraciones' 					=> $declaraciones,
			'cantidad_declaraciones'			=> count($array_declaraciones),
			'cantidad_declaraciones_multa'		=> count($array_declaraciones_multa),
			'id_ultima_declaracion'				=> $id_ultima_declaracion,
			'cantidad_pagos'					=> $cantidad_pagos,
			'extemporaneo'						=> $extemporaneo,
			'tiene_multa_formal'				=> $tiene_multa_formal,
			'posee_acta_recaudacion'			=> $posee_acta_recaudacion,
			'fecha_inicial'						=> $fecha_inicial,
			'fecha_final'						=> $fecha_final,
			'mensual'							=> $mensual
		];
	}
	

	/**
	 * Devuelve el monto total del aporte de una declaración (o declaraciones asociadas).
	 * Devuelve el monto con la reconversión (en caso de haber).
	 * El parametro solo necesita un array con todas la declaraciones. 
	 * El parametro "$consultar" solo es para cuando se quiera consultar el monto, esto es para que no se haga la reconversión en caso de haber.
	 */
	public static function obtenerMontoAporte(array $array_declaraciones, bool $consultar = false) : float{
		$monto_requerido_aporte = 0.00;
		/* var_dump($array_declaraciones);exit; */
		/* for($i = 0; $i < count($array_declaraciones); $i++){
			$decl = SidcaiDeclaracioncti::model()->findByPk($array_declaraciones[$i]);
			var_dump($decl);exit;
			if($consultar)
				$monto_requerido_aporte += $decl->decl_montorequerido;
			else
				$monto_requerido_aporte += bcdiv($decl->decl_montorequerido, '1', 2);
				var_dump($monto_requerido_aporte);
		} */
		/* var_dump($monto_requerido_aporte);
		exit; */
		/* return bcdiv($monto_requerido_aporte, '1', 2); */

		for($i = 0; $i < count($array_declaraciones); $i++){
			$decl = SidcaiDeclaracioncti::model()->findByPk($array_declaraciones[$i]);
			if($consultar)
				$monto_requerido_aporte = bcadd($monto_requerido_aporte, $decl->decl_montorequerido, 2); // Sumar directamente
			else
				$monto_requerido_aporte = bcadd($monto_requerido_aporte, bcdiv($decl->decl_montorequerido, '1', 2), 2); // Realizar la división y luego sumar
		}
		/* var_dump(floatval($monto_requerido_aporte)); */
		return floatval($monto_requerido_aporte);
	}


	/**
	 * Devuelve el monto total de los intereses moratorios de una declaración que ya ha sido creada (o declaraciones asociadas).
	 * Devuelve el monto con la reconversión (en caso de haber).
	 * El parametro necesita un array de las declaraciones con multa y el id de la empresa.
	* El parametro "$consultar" solo es para cuando se quiera consultar el monto, esto es para que no se haga la reconversión en caso de haber.
	 */
	public static function obtenerMontosInteresesMoratorios(array $array_declaraciones_multa, int $id_empresa, bool $consultar = false, bool $tiene_multa_formal) : float{
		$monto_requerido_intereses = 0.00;

		for($i = 0; $i < count($array_declaraciones_multa); $i++){
			$intereses = SidcaiMultaInteres::model()->find([
				'select' => 'mult_monto, fecha_registro',
				'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND apor_codigo_fk = :apor_codigo_fk AND multa_formal = :multa_formal',
				'params' => [
					':decl_codigo_fk' => $array_declaraciones_multa[$i],
					':mult_habilitada' => TRUE,
					':apor_codigo_fk' => $id_empresa,
					':multa_formal' => $tiene_multa_formal
				]

			]);

			if($intereses != null){
				if($consultar)
					$monto_requerido_intereses += $intereses->mult_monto;
				else
					$monto_requerido_intereses += bcdiv(self::reconversion($intereses->fecha_registro, $intereses->mult_monto), '1', 2);
			}
		}


		return bcdiv($monto_requerido_intereses, '1', 2);
	}

	/**
	 * Devuelve el monto total de la multa material de una declaración que ya ha sido creada (o declaraciones asociadas).
	 * Devuelve el monto con la reconversión (en caso de haber).
	 * El parametro solo necesita un array de las declaraciones con multa.
	 * El parametro "$consultar" solo es para cuando se quiera consultar el monto, esto es para que no se haga la reconversión en caso de haber.
	 */
	public static function obtenerMontosMultaMaterial(array $array_declaraciones_multa, bool $consultar = false) : float{
		$monto_requerido_multa_material = 0.00;

		for($i = 0; $i < count($array_declaraciones_multa); $i++){		
			$multa_material = SidcaiDeclaracionMulta::model()->find([
				'select' => 'decl_mult_monto, decl_mult_fecha',
				'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada',
				'params' => [
					':decl_codigo_fk' => $array_declaraciones_multa[$i],
					':mult_habilitada' => TRUE,
				]

			]);

			if($multa_material != null){			
				if($consultar)
					$monto_requerido_multa_material += $multa_material->decl_mult_monto;
				else
					$monto_requerido_multa_material += bcdiv(self::reconversion($multa_material->decl_mult_fecha, $multa_material->decl_mult_monto), '1', 2);
			}
		}

		return bcdiv($monto_requerido_multa_material, '1', 2);
	}

	public static function obtenerMontosMultaFormal(array $array_declaraciones_multa, bool $consultar = false){
		$monto_requerido_multa_formal = 0.00;

		if(count($array_declaraciones_multa) > 0 && !empty($array_declaraciones_multa)){
			$multa_formal = SidcaiDeclaracionMulta::model()->findAll([
				'select' => 'decl_mult_monto, decl_mult_fecha',
				'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND mult_codigo_fk != :mult_codigo_fk',
				'params' => [
					':decl_codigo_fk' => $array_declaraciones_multa[0],
					':mult_habilitada' => TRUE,
					':mult_codigo_fk' => 1
				]
			]);

			if($multa_formal != null){
				foreach($multa_formal as $m){
					if($consultar)
						$monto_requerido_multa_formal += $m->decl_mult_monto;
					else
						$monto_requerido_multa_formal += bcdiv(self::reconversion($m->decl_mult_fecha, $m->decl_mult_monto), '1', 2);
				}
			}
		}

		return bcdiv($monto_requerido_multa_formal, '1', 2);
	}

	/**
	 * Devuelve el monto Aportado por la empresa.
	  * El tercer parametro solo es para cuando se quiera consultar el monto, esto es para que no se haga la reconversión en caso de haber.
	  * El parametro "$consultar" solo es para cuando se quiera consultar el monto, esto es para que no se haga la reconversión en caso de haber.
	 */
	public static function obtenerMontoAportado(array $declaraciones, int $id_empresa, bool $consultar = false) : float{
		/* var_dump($declaraciones);
		exit; */
		$array_string = $declaraciones['array_declaraciones_string'];
		
		$mensual = false;
		foreach($declaraciones['declaraciones'] as $declaracion) {
			if($declaracion->decl_tipodeclaracion == 'M') {
				$mensual = true;
			}
		}
		$monto_aportado = 0.00;

		//var_dump($mensual);
		//exit; 
		/* try { */
			//code...
		if($mensual) {

			$pk_ultimo_detalle = SidcaiDeclaracionDetalle::model()->findAll([
				'select' => 'deta_codigo_pk',
				'condition' => 'codigo_declaraciones = :codigo_declaraciones AND decl_pago_aceptado AND apor_codigo_fk = :apor_codigo_fk AND decl_pago_aceptado = :decl_pago_aceptado',
				'params' => [
					':codigo_declaraciones' => $declaraciones['array_declaraciones_string'],
					':apor_codigo_fk' => $id_empresa,
					':decl_pago_aceptado' => TRUE
				],
				'order'  => 'deta_codigo_pk desc',
				'limit'  => 1
			]);
			// var_dump($pk_ultimo_detalle);
			//exit; 
			$detalles_totales = [];
			$swich = 0;
			while($swich == 0){
				//var_dump($array_string);exit;
				/* $array_string ="380860"; */
				$detalles = self::buscar_detalle($array_string, $id_empresa);
				if(!empty($detalles)){
					usort($detalles, ['FuncionesController','ordenarMayorMenor']);
					/* var_dump($detalles);exit; */
					foreach ($detalles as $key => $value) {
						/* var_dump($detalles);
						echo "<br>";
						echo "<br>";
						var_dump($value);exit; */
						//$detalles = explode(',', $value[0]);
						/* var_dump($value[0]);exit; */
						/* var_dump($detalles_totales);exit; */
						if(!in_array($value, $detalles_totales)){
							array_push($detalles_totales, $value);
							$evaluar = explode(',', $value[0]);
							$array_string = $evaluar[0];
							$swich = 0;
							break;
						}else{
							$swich = 1;
						}
						//exit;
					}
				}else{
					$detalles_totales = null;
					$swich = 1;
				}
				/* var_dump('hola');exit; */
			}

			/* var_dump($detalles_totales[0][0]);exit;
			echo "<br>";
			echo "<br>"; */
			if($detalles_totales != null){
				usort($detalles_totales, ['FuncionesController','ordenarMenorMayor']);
				/* var_dump($detalles_totales);exit;
				echo "<br>";
				echo "<br>"; */
				$cantidad_detalles = count($detalles_totales);
				$credito = 0.00;
				//if($cantidad_detalles > 1 || (isset($detalles_totales[0][5]) && $detalles_totales[0][5] == "multiple") ){
				if($cantidad_detalles > 1 || $declaraciones["array_declaraciones_string"] !=  $detalles_totales[0][0]){
					$credito = [];
					$creditos = [];
					foreach($detalles_totales as $key => $d){
						/* var_dump($key);
						echo "<br>";
						echo "<br>"; */
						if($key == 0){
							$aporte = self::calcular_aporte($d);
							/* var_dump($aporte);exit;
							//var_dump($d);
							echo "<br>";
							echo "<br>"; */
						}else{
							/* var_dump($pk_ultimo_detalle);exit; */
							//if($d[0] == $declaraciones['array_declaraciones_string']){
							if(!empty($pk_ultimo_detalle) && ($d[4] == $pk_ultimo_detalle[0]['deta_codigo_pk'])){
								/* var_dump($key);//exit;
								var_dump($d);
								echo "<br>";
								echo "<br>"; */
								//exit;
								/* var_dump($d[4]); 
								var_dump($pk_ultimo_detalle[0]['deta_codigo_pk']); 
								exit; */
								$aporte = self::calcular_aporte($d, $aporte, true);
								/* var_dump($aporte); exit; */
							}else{
								/* var_dump('no');
								var_dump($aporte);
								echo "<br>";
								echo "<br>"; */
								$aporte = self::calcular_aporte($d, $aporte);
								/* var_dump($key);
								var_dump($aporte);//exit;
								var_dump($d);
								echo "<br>";
								echo "<br>"; */
							}
							//var_dump($aporte);
							/* echo "<br>";
							echo "<br>"; */
						}
						/* var_dump($d[0]);exit; */
						/* var_dump($aporte);
						echo "<br>";
						echo "<br>"; */
						$fecha_declaracion = $d[2];
						if ($declaraciones["array_declaraciones_string"] != $d[0]) {
							$buscar = self::buscarCredito($d);
							if (!in_array($buscar, $credito)) {
								$credito[$key] = $buscar;
							}
						}					
						/* var_dump($credito);//exit;
						echo "<br>";
						echo "<br>"; */
						//codigto anterior
						//if(!empty($credito) && $credito[0] != null){
						//lm 30-10-2024
						if (!empty($credito) && isset($credito[0]) && $credito[0] != null) {
							if(!in_array($credito[0], $creditos)){
								array_push($creditos, $credito[0]);
							}
							$credito[$key][1] = $d[0];
						}
					}
					/* var_dump($creditos);exit; */
					$credito = 0.00;
					if (!empty($creditos)) {
						/* var_dump($creditos);exit; */
						foreach ($creditos as $key => $value) {
							if ($value[1] != $declaraciones['id_ultima_declaracion']) {
								$credito += $value[0];
							}						
						}
					}
					/* var_dump($credito);exit; */
				}else{
					/* var_dump($detalles_totales[0]);exit;
					echo "<br>";
					echo "<br>"; */
					/* var_dump($detalles_totales[0][0]);exit; */
					if ($declaraciones["array_declaraciones_string"] != $detalles_totales[0][0]) {
						$credito = self::buscarCredito($detalles_totales[0]);
					}
					/* var_dump($credito);exit; */
					$aporte = self::calcular_aporte($detalles_totales[0]);
					/* var_dump($aporte);exit; */
					if ($aporte < 0 && $credito != NULL) {
						if (is_array($credito) && isset($credito[0])) {
							$credito = $credito[0] + $aporte;
						} else {
							// Manejo de error o asignación de un valor por defecto
							$credito = $aporte; // O cualquier lógica que aplique en este caso
						}
					} else {
						if (is_array($credito) && isset($credito[0])) {
							$credito = $credito[0];
						} else {
							// Manejo de error o asignación de un valor por defecto
							$credito = 0; // O cualquier valor predeterminado
						}
					}
					
					/* var_dump($credito);exit; */
					$aporte = $detalles_totales[0][1];
					/* var_dump($aporte);exit; */
					$fecha_declaracion = $detalles_totales[0][2];
				}
				
				if($consultar){
					//$monto_aportado += $d->decl_monto;
					$monto_aportado += $aporte;
				}else{
					//$monto_aportado += bcdiv(self::reconversion($d->decl_fechapago, $d->decl_monto), '1', 2);
					//$monto_aportado += bcdiv(self::reconversion($fecha_declaracion, $aporte, false), '1', 2);
					$monto_aportado += $aporte;
					/* var_dump($monto_aportado);exit; */
				}
				$monto_aportado = number_format($monto_aportado, 2, '.', '');
				/* var_dump($monto_aportado);exit; */
				$monto_aportado = bcdiv($monto_aportado, '1', 2) + $credito;
				/* var_dump('llegue');
				var_dump($monto_aportado);
				exit; */
			}
			/* exit; */
		
		}else{
			//if(!$mensual) {
			/* var_dump('anual');exit; */
			$pagosMensuales = SidcaiDeclaracioncti::model()->findAll(
				array(
					'condition' => "apor_codigo_fk = :apor_codigo_fk AND
						decl_tipodeclaracion = 'M' AND
						esta_codigo_fk = 1003 AND
						decl_fechainicio_base >= :fecha_inicial AND
						decl_fechafin_base <= :fecha_final",
					'params' => array(
						':apor_codigo_fk' => $id_empresa,
						':fecha_inicial' => $declaraciones['fecha_inicial'],
						':fecha_final' => $declaraciones['fecha_final']
					),
				)
			);
			$total_aporte_mensual = 0;
			foreach($pagosMensuales as $pagoMensual) {
				$monto_aporte_number = FuncionesController::reconversion($pagoMensual->decl_fechadeclaracion, $pagoMensual->decl_montoaportado);
				$total_aporte_mensual += bcdiv($monto_aporte_number, '1', 2);
			}
			/* var_dump($declaraciones['declaraciones'][0]["decl_montoaportado"]);exit; */
			//$monto_aportado += bcdiv($total_aporte_mensual, '1', 2);
			$monto_aportado += bcdiv($total_aporte_mensual, '1', 2) + $declaraciones['declaraciones'][0]["decl_montoaportado"];
			//$monto_aportado = $declaraciones['declaraciones'][0]["decl_montoaportado"];
		}

		return $monto_aportado;
	}

	public static function buscarCredito($declaraciones) {
		if($declaraciones[5] == "multiple"){
			$array_codigos = explode(',', $declaraciones[0]);
			$ultimo_codigo = $array_codigos[count($array_codigos) - 1];
		}else{
			$ultimo_codigo = $declaraciones[0];
		}
		/* var_dump($declaraciones);exit; */
		$buscar_credito = SidcaiCreditoFiscal::model()->find([
			'condition' => 'apor_codigo_fk = :apor_codigo_fk AND decl_codigo_fk_destino = :decl_codigo_fk_destino',
			'params' => [
				':apor_codigo_fk' => $declaraciones[3],
				':decl_codigo_fk_destino' => $ultimo_codigo
			]
		]);
		//var_dump($buscar_credito);//exit;
		$credito = [];
		if($buscar_credito != NULL){
			$credito[0] = $buscar_credito["cred_monto"];
			$credito[1] = $ultimo_codigo;
			return $credito;
		}else{
			return NULL;
		}
	}

	public static function ordenarMenorMayor($a, $b) {
		// Comparamos los códigos para ordenar en función de ellos
		return strcmp($a[0], $b[0]);
	}

	public static function ordenarMayorMenor($a, $b) {
		// Comparamos los códigos para ordenar en función de ellos
		return strcmp($b[0], $a[0]);
	}

	public static function buscar_detalle($array_string, $id_empresa){
		/* $detalles = SidcaiDeclaracionDetalle::model()->findAll([
			'condition' => '(codigo_declaraciones = :codigo OR :codigo = ANY(string_to_array(codigo_declaraciones, \',\'))) AND apor_codigo_fk = :apor_codigo_fk AND decl_pago_aceptado = :decl_pago_aceptado',
			'params' => [
				':codigo' => $array_string,
				':apor_codigo_fk' => $id_empresa,
				':decl_pago_aceptado' => TRUE
			]
		]); */
		/* var_dump('llega');exit; */
		$detalles_totales = [];

		// Iterar sobre cada valor en $array_string
		foreach (explode(',', $array_string) as $codigo) {
			// Realizar la consulta para el código actual
			/* var_dump('hola');exit; */
			$detalles = SidcaiDeclaracionDetalle::model()->findAll([
				'condition' => '(:codigo = ANY(string_to_array(codigo_declaraciones, \',\'))) AND apor_codigo_fk = :apor_codigo_fk AND decl_pago_aceptado = :decl_pago_aceptado',
				'params' => [
					':codigo' => $codigo,
					':apor_codigo_fk' => $id_empresa,
					':decl_pago_aceptado' => TRUE
				]
			]);
			/* var_dump($detalles);
			echo "<br>";
			echo "<br>"; */
			//exit;
			// Agregar los detalles encontrados al array de detalles totales, asegurándonos de no agregar duplicados
			foreach ($detalles as $detalle) {
				$detalles_totales[$detalle->deta_codigo_pk] = $detalle;
			}
		}

		// Convertir el array asociativo a un array indexado
		$detalles_totales = array_values($detalles_totales);
		/* var_dump($detalles_totales);exit; */
		$detalles = [];
		foreach ($detalles_totales as $key => $value) {
			/* var_dump($value["codigo_declaraciones"]);exit; */
			$detalles[$key][0] = $value["codigo_declaraciones"];
			/* var_dump($detalles);exit; */
			$detalles[$key][1] = $value["decl_monto"];
			/* var_dump($detalles);exit; */
			$detalles[$key][2] = $value["decl_fechapago"];
			/* var_dump($detalles);exit; */
			$detalles[$key][3] = $value["apor_codigo_fk"];
			/* var_dump($detalles);exit; */
			$detalles[$key][4] = $value["deta_codigo_pk"];
			/* var_dump($detalles);exit; */
			$array_declaraciones = explode(",", $value["codigo_declaraciones"]);
			if(count($array_declaraciones) > 1){
				$detalles[$key][5] = "multiple";
				/* var_dump($detalles);exit; */
			}else{
				$detalles[$key][5] = "individual";
				/* var_dump($detalles);exit; */
			}
			/* var_dump($array_declaraciones);exit; */
		}
		/* var_dump($detalles);exit; */
		return $detalles;
	}

	public static function calcular_aporte($declaracion, $monto_anterior = null, $finalizado = false){
		/* var_dump($declaracion);exit; */
		
		$array_declaraciones = explode(",", $declaracion[0]);
		/* var_dump($array_declaraciones);exit; */
		$cantidad_declaraciones = count($array_declaraciones);
		/* var_dump($array_declaraciones);exit; */
		$monto_aportado = 0.00;
		foreach ($array_declaraciones as $key => $value) {
			$ad_array[0] = $value;
			$monto = self::obtenerMontoAporte($ad_array);
			/* var_dump($monto);exit; */
			$ultimo_indice = $cantidad_declaraciones - 1;
			if($key != $ultimo_indice){
				if ($key == 0 && $monto_anterior != null && !$finalizado) {
					/* var_dump('pasa por aquí'); */
					/* exit; */
					//if($declaracion_pendiente != ""){
						$monto -= $monto_anterior;
						/* var_dump('si'); */
					//}
					/* exit; */
					$declaracion[1] -= $monto;
				}else if($key == 0 && $monto_anterior != null && $finalizado){
					/* var_dump($declaracion[1] );
					var_dump($monto_anterior); */
					$declaracion[1] += $monto_anterior;
					$monto_aportado = $declaracion[1];
					break;
					/* var_dump($declaracion[1]);
					echo "<br>";
					echo "<br>"; */
				}else{
					$declaracion[1] -= $monto;
				}				
			}else{
				if($cantidad_declaraciones == 1){
					if($monto_anterior != null && !$finalizado){
						$monto_aportado = $declaracion[1] + $monto_anterior;
						/* var_dump($monto_aportado);exit; */
					}else if($monto_anterior != null && $finalizado){
						$monto_aportado = $declaracion[1] + $monto_anterior;
						/* var_dump($monto_aportado);exit; */
					}else{
						$monto_aportado = $declaracion[1];
						/* var_dump($monto_aportado);exit; */
					}
				}else{
					$monto_aportado = $declaracion[1];
				}				
			}

			/* $credito = self::buscarCredito($detalles_totales[0]);
			$monto_aportado += $credito; */
			/* var_dump($value);
			var_dump($monto);
			var_dump($declaracion[1]);
			echo "<br>";
			echo "<br>"; */
		}
		/* var_dump($monto_aportado);
		exit; */
		return $monto_aportado;
	}

	public static function obtenerInicioPeriodoGravable($aportante){
		$fecha_cierre = date("Y", strtotime($aportante->apor_fechacreacionempresa));
		$fecha_cierre = $fecha_cierre .'-'. $aportante->apor_mescierre .'-'. $aportante->apor_diacierre;
		$fecha_inicio = date("Y-m-d", strtotime($fecha_cierre." -1 year + 1 day"));
		// var_dump($fecha_inicio);exit; 
		return $fecha_inicio;
	}

	public static function obtenerInicioPeriodoGravableNew($aportante) {
		// Obtener la fecha de cierre
		$fecha_cierre = date("Y", strtotime($aportante->apor_fechacreacionempresa));
		//print_r($fecha_cierre);die();
		$fecha_cierre = $fecha_cierre . '-' . $aportante->apor_mescierre . '-' . $aportante->apor_diacierre;
	
		// Calcular la fecha de inicio del período gravable, que es 6 meses antes de la fecha de cierre
		$fecha_inicio = date("Y-m-d", strtotime($fecha_cierre . " +6 months + 1 day"));
	
		return $fecha_inicio;
	}
	

	/*public static function obtenerEstatusAportante($aportante) {
		// Obtener la fecha de inicio (por ejemplo: 2023-07-31)
		$fecha_inicio = self::obtenerInicioPeriodoGravable($aportante);
		$fecha_aportante_viejo = date("Y-m-d", strtotime(date("Y-m-d") . " -1 year"));
	
		$empresa_nueva = $fecha_inicio > $fecha_aportante_viejo;
	
		if (!$empresa_nueva) {
			$year_periodo_actual = date("-m-d", strtotime($fecha_inicio)) == "-01-01" ? date('Y') : date("Y", strtotime($fecha_aportante_viejo));
			$fecha_periodo_actual = $year_periodo_actual . date("-m-d", strtotime($fecha_inicio));
			$year_nuevo = $year_periodo_actual - 1;
	
			$inicio_periodo_fiscal_anterior = $year_nuevo . date('-m-d', strtotime($fecha_inicio));
			$final_periodo_fiscal_anterior = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior . " + 1 year - 1 day"));
	
			// Obtener el monto del periodo anterior
			$monto_aporte_periodo_anterior = SidcaiDeclaracioncti::model()->find(array(
				'select' => 'decl_ingresosbrutos',
				'condition' => 'apor_codigo_fk = :apor_codigo AND (esta_codigo_fk = 1003 OR esta_codigo_fk = 1004) AND decl_fechainicio_base = :decl_fechainicio_base AND decl_fechafin_base = :decl_fechafin_base',
				'params' => array(
					':apor_codigo' => $aportante["apor_codigo_pk"],
					':decl_fechainicio_base' => $inicio_periodo_fiscal_anterior,
					':decl_fechafin_base' => $final_periodo_fiscal_anterior
				),
				'limit' => 1
			));
	
			if ($monto_aporte_periodo_anterior["decl_ingresosbrutos"] !== NULL) {
				$tasa = SidcaiCambioTasa::model()->find(array(
					'condition' => 'cata_fecha <= :cata_fecha AND cata_habilitado = true',
					'params' => array(':cata_fecha' => $fecha_periodo_actual),
					'order' => 'cata_fecha DESC, cata_tasa DESC',
					'limit' => 1
				));
	
				if ($monto_aporte_periodo_anterior["decl_ingresosbrutos"] > $tasa["cata_tasa"] * 150000) {
					$objeto_aportante['aportante'] = TRUE;
					$objeto_aportante['periodo'] = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior . " + 1 year"));
					return $objeto_aportante;
				}
			}
	
			// Generar los 12 meses a partir de la fecha de inicio
			$fechas_mensuales = [];
			$fecha_actual = new DateTime($fecha_inicio);
			for ($i = 0; $i < 11; $i++) {
				// Agregar el último día del mes actual al arreglo
				$fechas_mensuales[] = $fecha_actual->format('Y-m-t');
				// Avanzar al siguiente mes
				$fecha_actual->modify('first day of next month');
			}
	
			$objeto_aportante['aportante'] = FALSE;
			$objeto_aportante['fechas_mensuales'] = $fechas_mensuales;
			return $objeto_aportante;
		} else {
			$objeto_aportante['aportante'] = FALSE;
			return $objeto_aportante;
		}
	}*/
	
	public static function obtenerEstatusAportante($aportante){
		// var_dump($aportante["apor_codigo_pk"]);exit; 
		$fecha_inicio = self::obtenerInicioPeriodoGravable($aportante);
		$fecha_aportante_viejo = date("Y-m-d", strtotime(date("Y-m-d")." -1 year"));
		///var_dump($fecha_inicio);exit; 

		if($fecha_inicio <= $fecha_aportante_viejo){
			$empresa_nueva = FALSE;
		}else{
			$empresa_nueva = TRUE;
		}
		//if($aportante->apor_fechacreacionempresa <= $fecha_aportante_viejo){
		if(!$empresa_nueva){

			//$year_periodo_actual = date("-m-d", strtotime($fecha_inicio)) == "-01-01" ? date('Y') : date("Y", strtotime($fecha_aportante_viejo));
			if (date("-m-d", strtotime($fecha_inicio)) == "-01-01") {
				$year_periodo_actual = date('Y');
			}else{
				//var_dump('llegue');exit; 
				$year_periodo_actual =  date('-m-d') >= date("-m-d", strtotime($fecha_inicio)) ? date('Y') : date("Y", strtotime($fecha_aportante_viejo));
			}
			$fecha_periodo_actual = $year_periodo_actual . date("-m-d", strtotime($fecha_inicio));
			//var_dump($fecha_periodo_actual);//exit; 
			$year_nuevo = $year_periodo_actual - 1;
			//var_dump($year_nuevo);exit; 

			// Construir la nueva fecha utilizando el año obtenido y el mes y día de la fecha original
			$inicio_periodo_fiscal_anterior = $year_nuevo . date('-m-d', strtotime($fecha_inicio));
			$final_periodo_fiscal_anterior = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior." + 1 year - 1 day"));
			//($inicio_periodo_fiscal_anterior);
			//var_dump($final_periodo_fiscal_anterior);//exit; 

			//Depuración
			//"Inicio periodo fiscal: " . $inicio_periodo_fiscal_anterior);
			//var_dump("Fin periodo fiscal: " . $final_periodo_fiscal_anterior);
			//die();

			//string(33) "Inicio periodo fiscal: 2023-09-01" string(30) "Fin periodo fiscal: 2024-08-31"

			



			$monto_aporte_periodo_anterior = SidcaiDeclaracioncti::model()->find(
				array(
					//'select' => 'decl_montorequerido',
					'select' => 'decl_ingresosbrutos',
					'condition' => 'apor_codigo_fk = :apor_codigo AND (esta_codigo_fk = 1003 OR esta_codigo_fk = 1004) AND  decl_fechainicio_base = :decl_fechainicio_base AND decl_fechafin_base = :decl_fechafin_base',
					'params' => array(
						':apor_codigo' => $aportante["apor_codigo_pk"],
						
						':decl_fechainicio_base' => $inicio_periodo_fiscal_anterior,
						':decl_fechafin_base' => $final_periodo_fiscal_anterior
					),
					'limit' => 1
				)
			);


			if($monto_aporte_periodo_anterior == NULL){
				$monto_aporte_periodo_anterior = SidcaiDeclaracioncti::model()->find(
					array(
						//'select' => 'decl_montorequerido',
						'select' => 'decl_ingresosbrutos',
						'condition' => 'apor_codigo_fk = :apor_codigo OR (esta_codigo_fk = 1003 OR esta_codigo_fk = 1004) AND  decl_fechainicio_base = :decl_fechainicio_base AND decl_fechafin_base = :decl_fechafin_base',
						'params' => array(
							':apor_codigo' => $aportante["apor_codigo_pk"],
							
							':decl_fechainicio_base' => $inicio_periodo_fiscal_anterior,
							':decl_fechafin_base' => $final_periodo_fiscal_anterior
						),
						'limit' => 1
					)
				);

			}

			//var_dump($monto_aporte_periodo_anterior);exit; 
			//revisa 27-11
			$declaracionesTodas = SidcaiDeclaracioncti::model()->findAll(
				array(
					'condition' => "apor_codigo_fk = :apor_codigo_fk AND (esta_codigo_fk != :estatus_1) AND decl_tipodeclaracion = 'M'",
					'params' => [
						':apor_codigo_fk' => Yii::app()->user->id,
						':estatus_1' => 1005,
					],
					'order' => 'decl_fechainicio ASC'
				)
			);

			$inicio = new DateTime($inicio_periodo_fiscal_anterior);
$fin = new DateTime($final_periodo_fiscal_anterior);

// Incluir el último mes (si corresponde)
$fin->modify('+1 day');

// Calcular la diferencia en meses
$diferencia = $inicio->diff($fin);
$meses = ($diferencia->y * 12) + $diferencia->m;

//var_dump("Meses entre las fechas: " . $meses);die();

$declaracionesTodas = SidcaiDeclaracioncti::model()->findAll(
    array(
        'condition' => 'apor_codigo_fk = :apor_codigo_fk 
                        AND esta_codigo_fk IN (1001, 1003, 1004, 1008) 
                        AND decl_tipodeclaracion = :decl_tipodeclaracion 
                        AND decl_fechainicio_base BETWEEN :decl_fechainicio_base_inicio AND :decl_fechainicio_base_fin',
        'params' => array(
            ':apor_codigo_fk' => $aportante->apor_codigo_pk,
            ':decl_tipodeclaracion' => 'M',
            ':decl_fechainicio_base_inicio' => $inicio_periodo_fiscal_anterior,
            ':decl_fechainicio_base_fin' => $final_periodo_fiscal_anterior,
        ),
    )
);


$declaracionesMensualesEnRango = count($declaracionesTodas);

//print_r($declaracionesMensualesEnRango);die();

$declaracionesAnualTodas = SidcaiDeclaracioncti::model()->findAll(
    array(
        'condition' => "apor_codigo_fk = :apor_codigo_fk AND (esta_codigo_fk != :estatus_1) AND decl_tipodeclaracion = 'O' AND 
                        decl_fechainicio >= :inicio AND decl_fechafin <= :fin",
        'params' => [
            ':apor_codigo_fk' => Yii::app()->user->id,
            ':estatus_1' => 1005,
            ':inicio' => $inicio_periodo_fiscal_anterior,
            ':fin' => $final_periodo_fiscal_anterior,
        ],
        'order' => 'decl_fechainicio ASC'
    )
);

$declaracionesAnualesalesEnRango = count($declaracionesAnualTodas);

//var_dump("Total de declaraciones anuales en el rango: " . $declaracionesAnualesalesEnRango);
//die();

			

 
			//var_dump($aportante["apor_codigo_pk"]);exit; 
			//var_dump($monto_aporte_periodo_anterior);exit; 
			//var_dump($monto_aporte_periodo_anterior["decl_ingresosbrutos"]);exit; 
			//if($monto_aporte_periodo_anterior["decl_montorequerido"] != NULL){
			if($monto_aporte_periodo_anterior["decl_ingresosbrutos"] != NULL){
				$tasa = SidcaiCambioTasa::model()->find(
					array(
						'condition' => 'cata_fecha <= :cata_fecha AND cata_habilitado = true',
						'params' => array(
							//':cata_fecha' => $aportante->apor_fechacreacionempresa
							':cata_fecha' => $fecha_periodo_actual
						),
						'order' => 'cata_fecha DESC, cata_tasa DESC',
						'limit' => 1
					)
				);

				$meses_esperados = 12;
                $meses_encontrados = count($declaracionesTodas);


				//echo $meses_encontrados .' ----------- '. $meses_esperados;die();
                //var_dump($inicio_periodo_fiscal_anterior);exit; 

				// var_dump($monto_aporte_periodo_anterior["decl_montorequerido"]);exit; 

				//if($tasa["cata_tasa"] * 150000 < $monto_aporte_periodo_anterior["decl_montorequerido"]){
				//if($tasa["cata_tasa"] * 150000 < $monto_aporte_periodo_anterior["decl_ingresosbrutos"]){
				if($monto_aporte_periodo_anterior["decl_ingresosbrutos"] > $tasa["cata_tasa"] * 150000 && $meses_encontrados == $meses_esperados){
					//var_dump('true 1');exit; 
					$objeto_aportante['aportante'] = TRUE;
					$objeto_aportante['periodo'] = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior." + 1 year"));

					//print_r($objeto_aportante);die();
					return $objeto_aportante;
				}elseif($monto_aporte_periodo_anterior["decl_ingresosbrutos"] > $tasa["cata_tasa"] * 150000 && $meses_encontrados !== $meses_esperados /*&& $declaracionesAnualesalesEnRango==NULL*/){
					//var_dump('true 2');exit; 
					 $objeto_aportante['aportante'] = TRUE;
					 if($meses_encontrados==0){
						$objeto_aportante['periodo'] = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior." + 1 year"));
					 }elseif($meses_encontrados==11){
						$objeto_aportante['periodo'] = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior.""));
					 }else{
						$objeto_aportante['periodo'] = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior." + 1 year"));
					 }
					 
 
					// print_r($objeto_aportante);die();
					 return $objeto_aportante;

				}elseif($meses_encontrados > 10 && $meses_encontrados !== $meses_esperados /*&& $declaracionesAnualesalesEnRango==NULL*/){
					//var_dump('true 3');exit; 
					 $objeto_aportante['aportante'] = TRUE;
					 $objeto_aportante['periodo'] = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior.""));
 
					// print_r($objeto_aportante);die();
					 return $objeto_aportante;

				}
				else{
					//var_dump('false');exit; 
					$objeto_aportante['aportante'] = FALSE;
					return $objeto_aportante;
				}
			}else{
				// var_dump('false');exit; 
				$objeto_aportante['aportante'] = FALSE;
				return $objeto_aportante;
			}			
		}else {
			// var_dump('false');exit; 
			$objeto_aportante['aportante'] = FALSE;
			return $objeto_aportante;
		}		
	}


	
	public static function obtenerEstatusConciliacion($aportante){
		/* var_dump($aportante);exit; */
		$fecha_inicio = self::obtenerInicioPeriodoGravable($aportante);
		$fecha_aportante_viejo = date("Y-m-d", strtotime(date("Y-m-d")." -1 year"));
		 //var_dump($fecha_inicio);exit; 
		if($fecha_inicio <= $fecha_aportante_viejo){
			$empresa_nueva = FALSE;
		}else{
			$empresa_nueva = TRUE;
		}



		$anio_actual = date('Y');


		/*$recaudos = SidcaiRecaudo::model()->findAll([
			'condition' => 'apor_codigo_fk = :apor_codigo AND tipo_codigo_fk = :tipo_documento AND reca_direccion LIKE :anio_actual',
			'params' => [
				':apor_codigo' => $aportante["apor_codigo_pk"],
				':tipo_documento' => 3,
				':anio_actual' => "%{$anio_actual}%", // Busca el año en cualquier parte de reca_direccion
			]
		]);

		echo "<pre>";
		print_r(count($recaudos));
		echo "<pre>";
		die();*/




		//var_dump($empresa_nueva);exit; 
		if(!$empresa_nueva){
			/*$registros_islr = SidcaiRecaudo::model()->find(
				array(
					'condition' => 'apor_codigo_fk = :apor_codigo AND tipo_codigo_fk = :tipo_documento ',
					'params' => array(
						':apor_codigo' => $aportante["apor_codigo_pk"],
						':tipo_documento' => 3,
					),
				)
			);*/

			/*$registros_islr = SidcaiRecaudo::model()->findAll([
				'condition' => 'apor_codigo_fk = :apor_codigo AND tipo_codigo_fk = :tipo_documento AND reca_direccion LIKE :anio_actual',
				'params' => [
					':apor_codigo' => $aportante["apor_codigo_pk"],
					':tipo_documento' => 3,
					':anio_actual' => "%{$anio_actual}%", // Busca el año en cualquier parte de reca_direccion
				]
			]);*/

			$registros_islr = SidcaiRecaudo::model()->find(
				array(
					'condition' => 'apor_codigo_fk = :apor_codigo AND tipo_codigo_fk = :tipo_documento ',
					'params' => array(
						':apor_codigo' => $aportante["apor_codigo_pk"],
						':tipo_documento' => 3,
					),
				)
			);




			//var_dump($registros_islr);exit; 

			if ($registros_islr != NULL) {
				/* var_dump($registros_islr);exit; */

				/* Se define cual será el primer periodo fical ya cerrado a verificar 
				dependiendo de la fecha de creación de la empresa. */
				// var_dump($fecha_inicio);exit; 
				$year_inicio = date('Y', strtotime($fecha_inicio));
				/* var_dump($year_inicio);exit; */
				/* if (date('-m-d', strtotime($fecha_inicio)) >= "-04-01") { */
				if ($fecha_inicio >= "2022-04-01") {
					$year_verificar = $year_inicio;
					/* $year_verificar = date('Y', strtotime($fecha_inicio)); */
					/* var_dump($year_inicio);exit; */
					/* $year_verificar = "2022"; */
				}else{
					/* $year_verificar = $year_inicio <= "2022" ? "2022" : "2023"; */
					$year_verificar = date('-m-d', strtotime($fecha_inicio)) >= "-04-01" ? "2022" : "2023";
				}
				//var_dump($year_verificar);exit; 
				
				/* Se define el periodo fiscal tope hasta donde el algorimo debe verificar existencia de
				registros de las casillas */
				//$year_periodo_actual = date("-m-d", strtotime($fecha_inicio)) == "-01-01" ? date('Y') : date("Y", strtotime($fecha_aportante_viejo));
				if (date("-m-d", strtotime($fecha_inicio)) == "-01-01") {
					$year_periodo_actual = date('Y');
				}else{
					/* var_dump('llegue');exit; */
					$year_periodo_actual =  date('-m-d') >= date("-m-d", strtotime($fecha_inicio)) ? date('Y') : date("Y", strtotime($fecha_aportante_viejo));
					//$year_periodo_actual =  date('-m-d') >= date("-m-d", strtotime($fecha_inicio)) ? date('Y') : date("Y", strtotime($fecha_aportante_viejo));

				}
				 //var_dump($fecha_aportante_viejo);exit; 
				//$inicio_periodo_actual = date('Y') . date("-m-d", strtotime($fecha_inicio));
				$inicio_periodo_actual = $year_periodo_actual . date("-m-d", strtotime($fecha_inicio));
				$final_periodo_actual = date("Y-m-d", strtotime($inicio_periodo_actual." + 1 year - 1 day"));
				
				//var_dump($inicio_periodo_actual);exit;  //"2025-12-31"
               // var_dump(strtotime($final_periodo_actual)).'    '.var_dump(strtotime(date('Y-m-d')));exit; 

				if ((date('Y-m-d')) >= strtotime($final_periodo_actual)) {
				//if (strtotime(date('Y-m-d')) >= strtotime($final_periodo_actual)) {
					$year_tope = date('Y', strtotime($final_periodo_actual));
					//echo 1;die();
				}else{

					//echo 2;die();
					/* var_dump($inicio_periodo_actual);exit; */
					$fecha_inicio_regular = date('Y') . "-01-01";
					/* var_dump($inicio_periodo_actual);exit; */
					//if ($inicio_periodo_actual == $fecha_inicio_regular) {
						if (date('Y-m-d') >= strtotime($final_periodo_actual)) {
						//var_dump('IGUAL');exit; 
						$year_tope = date('Y', strtotime($final_periodo_actual." - 1 year"));
					}else{
						// var_dump('DIFERENTE');exit; 
						/* var_dump($final_periodo_actual);exit; */
						/* $year_tope = date('Y', strtotime($final_periodo_actual." - 2 year")); */
						/* var_dump($inicio_periodo_actual);exit; */
						//$year_tope = date('-m-d', strtotime($fecha_inicio)) >= date('-m-d') ? "2022" : "2023";
						//$year_tope = date('-m-d', strtotime($fecha_inicio)) >= date('-m-d') ? date("Y", strtotime(date("Y")." -2 year")) : date("Y", strtotime(date("Y")." -1 year"));
						$year_tope = date('-m-d', strtotime($fecha_inicio)) >= date('-m-d') ? date("Y", strtotime(date("Y")." -2 year")) : date("Y", strtotime(date("Y")." -1 year"));

					}
				}
				//var_dump($year_verificar);
				//var_dump($fecha_inicio);
				//exit; 

				for ($year_verificar ; $year_verificar <= $year_tope ; $year_verificar++) { 
					$fecha = $year_verificar . date("-m-d", strtotime($fecha_inicio));
					$fecha_inicio_obj = new DateTime($fecha_inicio);

					// Obtener el mes de $fecha_inicio
					$mes_inicio = $fecha_inicio_obj->format('m');

					// Crear la nueva fecha con el año y el mes
					$fecha = $year_verificar . '-' . $mes_inicio . '-01';

					//print_r($fecha);die();

					// Convertir la nueva fecha a un objeto DateTime para asegurarse de que es válida
					$fecha_obj = new DateTime($fecha);

					// Formatear la fecha como desees
					$fecha_formateada = $fecha_obj->format('Y-m-d');


					//print_r($fecha);die();
					$conciliacion = SidcaiCasillasIslr::model()->findAll(
						array(
							'condition' => 'apor_codigo_fk = :apor_codigo AND periodo_fiscal = :periodo_fiscal ',
							'params' => array(
								':apor_codigo' => $aportante->apor_codigo_pk,
								':periodo_fiscal' => $fecha_formateada,
							),
						)
					);

					$conciliacionestotal=count($conciliacion);
					//echo $conciliacionestotal;
					//die();
					




					// var_dump($conciliacion);exit; 
					//var_dump($fecha_formateada);exit; //2022-09-01
					$fechaIn = new DateTime($fecha_formateada);

					$fechaIn->modify('+1 year');

				   $fechaFn = new DateTime($fecha_formateada);
                   $fechaFn->modify('+1 year +11 months');

				   $verificar_anual="";
				   $verificar_mensuales="";

				//print_r($year_verificar+1);die();

	//die();



					//Esta consulta se usa para ver que el año a verificar ya fue pagado por el modulo anual y se encuentra finalizado
					//En tal caso no aplica para la conciliación
					$verificar_anual = SidcaiDeclaracioncti::model()->find(
						array(
							'condition' => 'apor_codigo_fk = :apor_codigo_fk AND esta_codigo_fk IN (1003, 1004, 1008) AND decl_tipodeclaracion = :decl_tipodeclaracion AND decl_fechainicio_base::text LIKE :decl_fechainicio_base',
							'params' => array(
								':apor_codigo_fk' => $aportante->apor_codigo_pk,
								':decl_tipodeclaracion' => 'O',
								':decl_fechainicio_base' => '%'.$year_verificar. '%', 
							),
						)
					);

					$conciliacion2 = SidcaiCasillasIslr::model()->findAll(
						array(
							'condition' => 'apor_codigo_fk = :apor_codigo AND periodo_fiscal = :periodo_fiscal ',
							'params' => array(
								':apor_codigo' => $aportante->apor_codigo_pk,
								':periodo_fiscal' => date('Y-m-01', strtotime('-1 year', strtotime($inicio_periodo_actual))),
							),
						)
					);

					//var_dump($conciliacion2);exit; 







                    /*echo '<pre>';
					print_r(date('Y-m-d', strtotime('-1 year', strtotime($inicio_periodo_actual))));2024-01-01
					echo '<pre>';
					die();*/

					//print_r($inicio_periodo_actual.'                         '.$final_periodo_actual);die();

					$fecha_inicio_menos_un_anio = date('Y-m-01', strtotime(($inicio_periodo_actual)));
                    $fecha_fin_menos_un_anio = date('Y-m-d', strtotime('-1 year', strtotime($final_periodo_actual)));


				//	print_r($fecha_inicio_menos_un_anio.'                         '.$fecha_fin_menos_un_anio);die();




					$meses_encontrados=0;
                    $verificar_mensuales='';
					$verificar_pagosmensuales='';
					$verificar_mensuales = SidcaiDeclaracioncti::model()->findAll(
						array(
							'condition' => 'apor_codigo_fk = :apor_codigo_fk 
											AND esta_codigo_fk IN (1001, 1003, 1004, 1008) 
											AND decl_tipodeclaracion = :decl_tipodeclaracion 
											AND decl_fechainicio_base BETWEEN :decl_fechainicio_base_inicio AND :decl_fechainicio_base_fin',
							'params' => array(
								':apor_codigo_fk' => $aportante->apor_codigo_pk,
								':decl_tipodeclaracion' => 'M',
								':decl_fechainicio_base_inicio' => $fecha_inicio_menos_un_anio,
								':decl_fechainicio_base_fin' => $fecha_fin_menos_un_anio,
							),
						)
					);

					$verificar_pagosmensuales = SidcaiDeclaracioncti::model()->findAll(
						array(
							'condition' => 'apor_codigo_fk = :apor_codigo_fk 
											AND esta_codigo_fk IN (1001, 1008) 
											AND decl_tipodeclaracion = :decl_tipodeclaracion 
											AND decl_fechainicio_base BETWEEN :decl_fechainicio_base_inicio AND :decl_fechainicio_base_fin',
							'params' => array(
								':apor_codigo_fk' => $aportante->apor_codigo_pk,
								':decl_tipodeclaracion' => 'M',
								':decl_fechainicio_base_inicio' => $fecha_inicio_menos_un_anio,
								':decl_fechainicio_base_fin' => $fecha_fin_menos_un_anio,
							),
						)
					);
					

					/*echo '<pre>';
					print_r(count($verificar_pagosmensuales));
					echo '<pre>';
					die();*/
					$meses_esperados = 12;
                    $meses_encontrados = count($verificar_mensuales);
					$pagos_encontrados= count($verificar_pagosmensuales);


					$resultados = Yii::app()->db->createCommand()
					->select('
						MIN(decl_fechainicio_base) as fecha_minima,
						MAX(decl_fechafin_base) as fecha_maxima
					')
					->from('sidcai_declaracioncti')
					->where('
						apor_codigo_fk = :apor_codigo_fk
						AND esta_codigo_fk IN (1001, 1003, 1004, 1008)
						AND decl_tipodeclaracion = :decl_tipodeclaracion
					', array(
						':apor_codigo_fk' => $aportante->apor_codigo_pk,
						':decl_tipodeclaracion' => 'O'
					))
					->queryRow();
				
				if ($resultados) {
					$fechaMinima = new DateTime($resultados['fecha_minima']);
					$fechaMaxima = new DateTime($resultados['fecha_maxima']);
					$hoy = new DateTime();
				
					// Ajustamos la fecha límite basada en el período establecido
					$fechaLimite = clone $fechaMaxima;
					$fechaLimite->modify('+1 year')->modify('-1 day'); // Ajusta al final del año siguiente
				
					// Si la fecha máxima es menor al límite, hay años faltantes
					if ($fechaMaxima < $fechaLimite) {
						// Obtenemos el año de la fecha máxima y el año límite
						$anioMaximo = $fechaMaxima->format('Y');
						$anioLimite = $fechaLimite->format('Y');
				
						// Array para almacenar los años faltantes completos
						$aniosFaltantes = [];
				
						// Verificamos cada año desde el siguiente al año máximo hasta el año límite
						for ($anio = $anioMaximo + 1; $anio <= $anioLimite; $anio++) {
							$aniosFaltantes[] = $anio;
						}
				
						if (!empty($aniosFaltantes)) {
							$year_verificar = $aniosFaltantes[0];
				
							// Generar rangos de fechas de cada año faltante basados en el mes y día de la fecha de inicio del período
							$periodosAnualesFaltantes = [];
							$mesInicio = $fechaMinima->format('m');
							$diaInicio = $fechaMinima->format('d');
							$mesFin = $fechaMaxima->format('m');
							$diaFin = $fechaMaxima->format('d');

							
				
							foreach ($aniosFaltantes as $anio) {
								$periodosAnualesFaltantes[] = [
									'inicio' => $anio . '-' . $mesInicio . '-' . $diaInicio,
									'fin' => $anio . '-' . $mesFin . '-' . $diaFin,
								];
							}

							//print_r($periodosAnualesFaltantes);die();
				
							$array_aportante['conciliacion'] = TRUE;
							$array_aportante['periodo'] = $periodosAnualesFaltantes[0]['inicio'];
							$array_aportante['data'] = $conciliacion != NULL ? $conciliacion : NULL;
							return $array_aportante;
						} else {
							// No hay años completos faltantes
						}
					} else {
						// No hay períodos anuales faltantes
					}
				}
				



					
					if ($verificar_anual == Null && $meses_encontrados==0 && $pagos_encontrados==0) {

						//echo 'aca 1';die();
						/* Si se encuentra al menos un registro no finalizado ó ningún registro
						se devuelve TRUE para habilitar la opción de conciliación en el menú de la empresa */
						//if($conciliacion == NULL || $conciliacion['estatus_fk'] != 8){
						if ($conciliacion === NULL || ($conciliacion['estatus_fk'] ?? null) != 8) {

							//echo '2';die();
							$array_aportante['conciliacion'] = TRUE;
							$array_aportante['periodo'] = $fecha;
							$array_aportante['data'] = $conciliacion != NULL ? $conciliacion : NULL;
							return $array_aportante;
							break;
						}
					}




			
					



					if ($verificar_mensuales != Null) {

						if(isset($conciliacion['estatus_fk'])){
                          $esta_c=$conciliacion['estatus_fk'];
						}else{

							$esta_c=NULL;


						}

								//print_r($meses_esperados);die();

							//	echo 'aca 3';die();

							//echo $esta_c; 8
							
							//echo $meses_encontrados; die();12

							//echo $meses_esperados; die();
								/* Si se encuentra al menos un registro no finalizado ó ningún registro
								se devuelve TRUE para habilitar la opción de conciliación en el menú de la empresa */
								//if(($conciliacion == NULL || isset($conciliacion['estatus_fk']) != 8) && ($meses_encontrados == $meses_esperados)){
						if (($conciliacion == NULL || $esta_c!= 8) && ($meses_encontrados == $meses_esperados && $esta_c!= 8) && $pagos_encontrados==0) {
							//echo 'aca 2-1 -----';die();

							if($conciliacion2==NULL){

								$anioc = date("Y", strtotime($fecha_inicio_menos_un_anio)); // Extrae el año
							$mesc = date("m-d", strtotime($fecha)); // Extrae el año

							$array_aportante['conciliacion'] = TRUE;
							$array_aportante['periodo'] = $anioc.'-'.$mesc;
							$array_aportante['data'] = $conciliacion != NULL ? $conciliacion : NULL;
							return $array_aportante;
							break;


							}

							$verificar_pagos_mensuales = SidcaiDeclaracioncti::model()->findAll(
								array(
									'condition' => 'apor_codigo_fk = :apor_codigo_fk 
													AND esta_codigo_fk IN (1003, 1004) 
													AND decl_tipodeclaracion = :decl_tipodeclaracion 
													AND decl_fechainicio_base BETWEEN :decl_fechainicio_base_inicio AND :decl_fechainicio_base_fin',
									'params' => array(
										':apor_codigo_fk' => $aportante->apor_codigo_pk,
										':decl_tipodeclaracion' => 'M',
										':decl_fechainicio_base_inicio' => $fecha_inicio_menos_un_anio,
										':decl_fechainicio_base_fin' => $fecha_fin_menos_un_anio,
									),
								)
							);

							$conciliacion_pendiente = SidcaiCasillasIslr::model()->findByAttributes(array(
								'apor_codigo_fk' => $aportante->apor_codigo_pk,
								'periodo_fiscal' => $fecha_inicio_menos_un_anio,
								/* 'estatus_fk' => 6, */
							));
							 //var_dump($conciliacion_pendiente);exit; 
							
							//print_r(count($verificar_pagos_mensuales));die();
							//print_r($fecha_inicio_menos_un_anio.'                '.$fecha_fin_menos_un_anio);die();
							//$anio = date("Y", strtotime($fecha)); // Extrae el año
                           // echo $anio; // Salida: 2023

                            if($meses_esperados==count($verificar_pagos_mensuales) && ($conciliacion_pendiente != NULL && $conciliacion_pendiente["estatus_fk"]!=8 )){

							//echo "aca    que paso";die();

							$anioc = date("Y", strtotime($fecha_inicio_menos_un_anio)); // Extrae el año
							$mesc = date("m-d", strtotime($fecha)); // Extrae el año
                          

							$array_aportante['conciliacion'] = TRUE;
							$array_aportante['periodo'] = $anioc.'-'.$mesc;
							$array_aportante['data'] = $conciliacion != NULL ? $conciliacion : NULL;
							return $array_aportante;
							break;
						    }else{
								$array_aportante['conciliacion'] = FALSE;
				            return $array_aportante;

							}
						}else{
							$array_aportante['conciliacion'] = FALSE;
				            return $array_aportante;

						}
					}
				}

				$array_aportante['conciliacion'] = FALSE;
				return $array_aportante;
			}else{
				/* var_dump('false');exit; */
				$array_aportante['conciliacion'] = FALSE;
				return $array_aportante;
			}
		}else{
			/* var_dump('false');exit; */
			$array_aportante['conciliacion'] = FALSE;
			return $array_aportante;
		}
	}



	public static function consultar_declaracion_pendiente($declaracion){
		$declaracion_pendiente = SidcaiDeclaracionDetalle::model()->findAll([
			'condition' => '(:codigo = ANY(string_to_array(codigo_declaraciones, \',\'))) AND apor_codigo_fk = :apor_codigo_fk AND decl_pago_aceptado = true o OR ',
			'params' => [
				':codigo' => $declaracion[0],
				':apor_codigo_fk' => $declaracion[3],
				':decl_pago_aceptado' => FALSE
			]
		]);
		/* var_dump($declaracion_pendiente);
		exit; */
		return $declaracion_pendiente;
	}

	public static function calcular_monto_old($declaracion_detalle,$declaraciones_verificar){
		$array_declaraciones = explode(",", $declaracion_detalle['codigo_declaraciones']);
		$pago = $declaracion_detalle["decl_monto"];
		/* var_dump($declaracion_detalle["apor_codigo_fk"]);exit; */
		/* var_dump(array_map('intval', $array_declaraciones));
		var_dump($pago);
		echo "<br>";
		echo "<br>";
		var_dump($declaraciones_verificar);
		echo "<br>";
		echo "<br>"; */
		//exit;
		/* var_dump($declaraciones_verificar);
		echo "<br>";
		echo "<br>"; */
		if (array_map('intval', $array_declaraciones) != $declaraciones_verificar) {
			// Verificar si hay una sola declaración
			//if (count($declaraciones_verificar) == 1 || in_array($d, $declaraciones_verificar)) {
			foreach ($array_declaraciones as $d) {
				if (in_array($d, $declaraciones_verificar)) {
					$declaracion[0] = $d;
					$monto = self::obtenerMontoAporte($declaracion);
					/* var_dump($pago);
					var_dump($declaracion);
					var_dump($monto); */
					foreach ($array_declaraciones as $key => $ad) {
						$ad_array[0] = $ad;
						var_dump($ad_array);
						if($ad != $d){
							/* var_dump($key); */
							if($key == 0){
								$detalles = SidcaiDeclaracionDetalle::model()->findAll([
									'condition' => '(:codigo = ANY(string_to_array(codigo_declaraciones, \',\'))) AND apor_codigo_fk = :apor_codigo_fk AND decl_pago_aceptado = :decl_pago_aceptado',
									'params' => [
										':codigo' => $ad,
										':apor_codigo_fk' => $declaracion_detalle["apor_codigo_fk"],
										':decl_pago_aceptado' => TRUE
									],
									'order'  => 'deta_codigo_pk asc',
									'limit'  => 1

								]);
								/* var_dump($detalles);exit; */
								$pago -= $monto;
							}
							$monto = self::obtenerMontoAporte($ad_array);
							$pago -= $monto;
							/* var_dump($monto); */
						}
					}
					/* var_dump($pago); */
					echo "<br>";
					echo "<br>";
				}else{
					var_dump($d);
					echo "<br>";
					echo "<br>";
				}
			}
		}
		/* var_dump($pago);
		echo "<br>";
		echo "<br>"; */
		exit;
		return $pago;
	}

	/**
	 *	Devuelve el monto requerido que la empresa tiene que aportar (incluyendo los intereses de mora, multa material y multa formal)
	 */
	public static function obtenerMontoRequerido(array $declaraciones, int $id_empresa, bool $consultar = false) : float{
		/* var_dump($declaraciones["declaraciones"][0]["decl_tipodeclaracion"]);exit; */
		/* foreach ($declaraciones as $key => $value) {
			var_dump($value);
			echo "<br>";
			echo "<br>";
		}exit; */
		/* var_dump($declaraciones["declaraciones"][0]['decl_fechainicio_base']);exit;
		if($declaraciones["declaraciones"][0]["decl_tipodeclaracion"] == "M"){
			$monto_aporte = self::reconversion($declaraciones["declaraciones"][0]["decl_fechadeclaracion"],self::obtenerMontoAporte($declaraciones['array_declaraciones']),false);
		}else{

			$monto_aporte = self::reconversion(false,self::obtenerMontoAporte($declaraciones['array_declaraciones']));
		} */
		
		$fecha_inicio = $declaraciones["declaraciones"][0]['decl_fechainicio_base'];
		$tipo_declaracion = $declaraciones["declaraciones"][0]["decl_tipodeclaracion"];
		if($tipo_declaracion == "O" && $fecha_inicio < '2021-04-06'){
			$monto_aporte = self::reconversion($declaraciones["declaraciones"][0]["decl_fechadeclaracion"],self::obtenerMontoAporte($declaraciones['array_declaraciones']),false);
		}else{
			$monto_aporte = self::reconversion($declaraciones["declaraciones"][0]["decl_fechadeclaracion"],self::obtenerMontoAporte($declaraciones['array_declaraciones']),false);
		}
		/* var_dump($monto_aporte);exit; */
		$monto_intereses = 0.00;
		$monto_multa_material = 0.00;
		$monto_multa_formal = 0.00;

		if($declaraciones['tiene_multa']){
			$monto_intereses 		= self::obtenerMontosInteresesMoratorios($declaraciones['array_declaraciones_multa'], $id_empresa, $consultar, $declaraciones['tiene_multa_formal']);
			$monto_multa_material 	= self::obtenerMontosMultaMaterial($declaraciones['array_declaraciones_multa'], $consultar);
			$monto_multa_formal = self::obtenerMontosMultaFormal($declaraciones['array_declaraciones_multa'], $consultar);
		}
		return ($monto_aporte + $monto_intereses + $monto_multa_material + $monto_multa_formal);
	}

	/**
	 * Devuelve el monto faltante de la suma de Aporte y en caso de tener intereses moratorios y multa material.
	 */
	public static function obtenerMontoFaltante(array $declaraciones, int $id_empresa, bool $consultar = false) : float{
		// Se busca si tiene crédito fiscal
		$buscar_credito = SidcaiCreditoFiscal::model()->find([
			'condition' => '(apor_codigo_fk = :apor_codigo_fk AND cred_habilitado = :cred_habilitado) OR (apor_codigo_fk = :apor_codigo_fk AND decl_codigo_fk_destino = :decl_codigo_fk_destino) ',
			'params' => [
				':apor_codigo_fk' => $id_empresa,
				':cred_habilitado' => TRUE,
				':decl_codigo_fk_destino' => $declaraciones['id_ultima_declaracion'],
			]
		]);

		//print_r($buscar_credito); die();

		$monto_credito_fiscal = 0.00;

		if($buscar_credito != null){
			if($consultar)
				$monto_credito_fiscal = $buscar_credito->cred_monto;
			else
				$monto_credito_fiscal = self::reconversion($buscar_credito->cred_fecha, $buscar_credito->cred_monto);
			$monto_credito_fiscal = bcdiv($monto_credito_fiscal, '1', 2);
		}

		$monto_requerido = self::obtenerMontoRequerido($declaraciones, $id_empresa, $consultar);
		/* $monto_requerido = number_format($monto_requerido, 2, '.', ''); */
		$monto_aportado  = self::obtenerMontoAportado($declaraciones, $id_empresa, $consultar);
		$monto_aportado = $monto_aportado + $monto_credito_fiscal;

		//var_dump("monto_aportado    ". $monto_aportado."           ");
		//var_dump("monto_requerido    ".$monto_requerido);exit; //lm 16-05-2025
		$monto_faltante = $monto_requerido - $monto_aportado;
		$monto_faltante = number_format($monto_faltante, 2, '.', '');
		/* var_dump($monto_faltante);exit; */
		return bcdiv($monto_faltante, '1', 2);
	}


	/**
	 * Crea un nuevo registro de Intereses Moratorios y Multa Material (En caso de que hallan cambiado por que la empresa aún no ha pagado y se pasó su 15 días o su última declaración se volvió extemporanea)
	 */
	public static function revisarInteresesMulta(array $declaraciones, int $id_empresa) : bool{
		if($declaraciones['tiene_multa']){
			$date = new DateTime("now", new DateTimeZone('America/Caracas')); 
			$hoy = $date->format('Y-m-d H:i:s');

			$declaracion = SidcaiDeclaracioncti::model()->findByPk($declaraciones['array_declaraciones'][0]);

			$transaction = $declaracion->dbConnection->beginTransaction();

			$analista = null;

			// Se busca el analista que tiene asignado la declaración.
			$buscar_analista = SidcaiDeclaracionAnalista::model()->find([
				'select' => 'usua_codigo_fk',
				'condition' => 'decl_codigo_fk = :decl_codigo_fk AND usua_habilitado = :usua_habilitado',
				'params' => [
					':decl_codigo_fk' => $declaraciones['id_ultima_declaracion'],
					'usua_habilitado' => TRUE
				]
			]);

			if($buscar_analista != null)
				$analista = $buscar_analista->usua_codigo_fk;

			// Intereses Moratorios
			for($i = 0; $i < count($declaraciones['array_declaraciones_multa']); $i++){	
				$monto = 0.00;
				$monto_del_dia = 0.00;

				if($declaraciones['tiene_multa_formal'])
					$monto_del_dia = self::obtenerInteresesMoratoriosMultaFormal($declaraciones['array_declaraciones_multa'][$i], $declaraciones['array_declaraciones'], $declaraciones['array_declaraciones_multa']);
				else
					$monto_del_dia = self::obtenerInteresesMoratorios($declaraciones['array_declaraciones_multa'][$i], $declaraciones['array_declaraciones'], false, false);
                // arreglo de bug del recalculo de interes moratorio
				$intereses = SidcaiMultaInteres::model()->find([
					//'select' => 'fecha_registro, mult_monto, analista_fk, mult_habilitada,decl_codigo_fk',
					'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND multa_formal = :multa_formal',
					'params' => [
						':decl_codigo_fk' 	=> $declaraciones['array_declaraciones_multa'][$i],
						':mult_habilitada' 	=> TRUE,
						':multa_formal' 	=> $declaraciones['tiene_multa_formal']
					],
					'order' => 'mult_codigo_pk DESC'
				]);

				if($intereses != null){
					$monto = bcdiv(self::reconversion($intereses->fecha_registro, $intereses->mult_monto), '1', 2);

					if($monto != $monto_del_dia){	
						$intereses->mult_habilitada = 0;
						if(!$intereses->save()){
							$transaction->rollBack();
							return false;
						}

						$nuevo_intereses = new SidcaiMultaInteres;
						$nuevo_intereses->apor_codigo_fk 	= $id_empresa;
						$nuevo_intereses->decl_codigo_fk  	= $declaraciones['array_declaraciones_multa'][$i];
						$nuevo_intereses->mult_monto 		= $monto_del_dia;
						$nuevo_intereses->analista_fk 		= $analista;
						$nuevo_intereses->fecha_registro 	= $hoy;

						if(!$nuevo_intereses->save()){
							$transaction->rollBack();
							return false;
						}
					}
				}else{
					// Ingresará al else si la última declaración pasó a ser extemporanea
					$nuevo_intereses = new SidcaiMultaInteres;
					$nuevo_intereses->apor_codigo_fk 	= $id_empresa;
					$nuevo_intereses->decl_codigo_fk  	= $declaraciones['array_declaraciones_multa'][$i];
					$nuevo_intereses->mult_monto 		= $monto_del_dia;
					$nuevo_intereses->analista_fk 		= $analista;
					$nuevo_intereses->fecha_registro 	= $hoy;

					if(!$nuevo_intereses->save()){
						$transaction->rollBack();
						return false;
					}
				}
			}


			// Multa material
			for($i = 0; $i < count($declaraciones['array_declaraciones_multa']); $i++){	
				$monto = 0.00;
				$monto_del_dia = 0.00;

				$declaracion = SidcaiDeclaracioncti::model()->findByPk($declaraciones['array_declaraciones_multa'][$i]);
				$monto_del_dia = self::obtenerMultaMaterial($declaracion->decl_montorequerido);
                // arreglando la multa material
				$multa_material = SidcaiDeclaracionMulta::model()->find([
					//'select' => 'decl_mult_fecha, decl_mult_monto, usua_codigo_fk, mult_habilitada',
					'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND mult_codigo_fk = :mult_codigo_fk',
					'params' => [
						':decl_codigo_fk' 	=> $declaraciones['array_declaraciones_multa'][$i],
						':mult_habilitada' 	=> TRUE,
						':mult_codigo_fk' 	=> 1
					],
					'order' => 'decl_mult_codigo_pk DESC'
				]);

				if($multa_material != null){
					$monto = bcdiv(self::reconversion($multa_material->decl_mult_fecha, $multa_material->decl_mult_monto), '1', 2);
				   
					if($monto != $monto_del_dia){
						$multa_material->mult_habilitada = 0;
						if(!$multa_material->save()){
							$transaction->rollBack();
							return false;
						}

						$nuevo_multa_material = new SidcaiDeclaracionMulta;
						$nuevo_multa_material->decl_codigo_fk 	= $declaraciones['array_declaraciones_multa'][$i];
						$nuevo_multa_material->usua_codigo_fk 	= $analista;
						$nuevo_multa_material->mult_codigo_fk  	= 1;
						$nuevo_multa_material->decl_mult_monto 	= $monto_del_dia;
						$nuevo_multa_material->decl_mult_fecha 	= $hoy;

						if(!$nuevo_multa_material->save()){
							$transaction->rollBack();
							return false;
						}
					}
				}else{
					$nuevo_multa_material = new SidcaiDeclaracionMulta;
					$nuevo_multa_material->decl_codigo_fk 	= $declaraciones['array_declaraciones_multa'][$i];
					$nuevo_multa_material->usua_codigo_fk 	= $analista;
					$nuevo_multa_material->mult_codigo_fk  	= 1;
					$nuevo_multa_material->decl_mult_monto 	= $monto_del_dia;
					$nuevo_multa_material->decl_mult_fecha 	= $hoy;

					if(!$nuevo_multa_material->save()){
						$transaction->rollBack();
						return false;
					}
				}
			}

			$transaction->commit();
		}
		return true;
	}


	/**
	 * Devuelve los montos de los intereses en un array con su respectiva declaración en el acta de reparo de recaúdaíón.
	 */
	public static function detallesInteresesMoratoriosActa(array $array_declaraciones_multa, bool $consultar = false, bool $fiscalizacion = false) : array{
		$devolver = [];

		for($i = 0; $i < count($array_declaraciones_multa); $i++){	
			if($fiscalizacion){
				$intereses = SidcaiMultaInteres::model()->find([
					'select' => 'fecha_registro, mult_monto, mult_habilitada',
					'condition' => 'decl_codigo_fk = :decl_codigo_fk AND multa_formal = :multa_formal',
					'params' => [
						':decl_codigo_fk' 	=> $array_declaraciones_multa[$i],
						':multa_formal' 	=> TRUE,
					],
					'order' => 'mult_codigo_pk DESC'
				]);

				if($intereses != null){
					if($consultar){
						if($intereses->mult_habilitada == true)
							$monto = self::reconversion($intereses->fecha_registro,$intereses->mult_monto);
						else
							continue;
					}
					else
						$monto = bcdiv(self::reconversion(false, $intereses->mult_monto), '1', 2);

					$devolver[$array_declaraciones_multa[$i]] = bcdiv($monto, '1', 2);
				}
			}else{
				// Primero se verifica si existe intereses con multa formal
				$existe_multa_formal = SidcaiMultaInteres::model()->find([
					'select' => 'mult_habilitada',
					'condition' => 'decl_codigo_fk = :decl_codigo_fk AND multa_formal = :multa_formal',
					'params' => [
						':decl_codigo_fk' 	=> $array_declaraciones_multa[$i],
						':multa_formal' 	=> TRUE,
					],
					'order' => 'mult_codigo_pk DESC'
				]);

				$tiene_multa_formal = ($existe_multa_formal != null) ? true : false;

				$intereses = SidcaiMultaInteres::model()->find([
					'select' => 'fecha_registro, mult_monto, mult_habilitada',
					'condition' => 'decl_codigo_fk = :decl_codigo_fk AND multa_formal = :multa_formal',
					'params' => [
						':decl_codigo_fk' 	=> $array_declaraciones_multa[$i],
						':multa_formal' 	=> FALSE,
					],
					'order' => 'mult_codigo_pk DESC'
				]);

				if($intereses != null){
					if($consultar){
						if($intereses->mult_habilitada == true || $tiene_multa_formal == true)
							$monto = self::reconversion($intereses->fecha_registro,$intereses->mult_monto);
						else
							continue;
					}
					else
						$monto = bcdiv(self::reconversion(false, $intereses->mult_monto), '1', 2);

					$devolver[$array_declaraciones_multa[$i]] = bcdiv($monto, '1', 2);
				}
			}
		}

		return $devolver;
	}

	/**
	 * Devuelve los montos de los intereses en un array con su respectiva declaración
	 * 150000 => 49416.15
	 * 150001 => 4324325.43
	 * 150002 => 496546547416.75
	 */
	public static function detallesInteresesMoratorios(array $array_declaraciones_multa, bool $consultar = false, bool $tiene_multa_formal = false) : array{
		$devolver = [];


		for($i = 0; $i < count($array_declaraciones_multa); $i++){	

			$intereses = SidcaiMultaInteres::model()->find([
				'select' => 'fecha_registro, mult_monto',
				'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND multa_formal = :multa_formal',
				'params' => [
					':decl_codigo_fk' 	=> $array_declaraciones_multa[$i],
					':mult_habilitada' 	=> TRUE,
					':multa_formal' 	=> $tiene_multa_formal,
				],
				'order' => 'mult_codigo_pk DESC'
			]);

			if($intereses != null){
				if($consultar)
					$monto = $intereses->mult_monto;
				else
					$monto = bcdiv(self::reconversion($intereses->fecha_registro, $intereses->mult_monto), '1', 2);

				$devolver[$array_declaraciones_multa[$i]] = bcdiv($monto, '1', 2);
			}
		}

		return $devolver;
	}

	/**
	 * Devuelve los montos de las multas materiales en un array con su respectiva declaración
	 * 150000 => 49416.15
	 * 150001 => 4324325.43
	 * 150002 => 496546547416.75
	 */
	public static function detallesMultaMaterial(array $array_declaraciones_multa, bool $consultar = false) : array{
		$devolver = [];

		for($i = 0; $i < count($array_declaraciones_multa); $i++){		
			$multa_material = SidcaiDeclaracionMulta::model()->find([
    			'select' => 'decl_mult_monto, decl_mult_fecha',
    			'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND mult_codigo_fk = :mult_codigo_fk',
    			'params' => [
    				':decl_codigo_fk' => $array_declaraciones_multa[$i],
    				':mult_habilitada' => TRUE,
    				':mult_codigo_fk' => 1
    			],
    			'order' => 'decl_mult_codigo_pk DESC'
    		]);

			if($multa_material != null){
				if($consultar)
					$monto = self::reconversion($multa_material->decl_mult_fecha,$multa_material->decl_mult_monto);
				else
					$monto = bcdiv(self::reconversion($multa_material->decl_mult_fecha, $multa_material->decl_mult_monto), '1', 2);

				$devolver[$array_declaraciones_multa[$i]] = bcdiv($monto, '1', 2);
			}
		}

		return $devolver;
	}



	/**
	 * Devuelve los montos de las multas formales en un array con su respectiva declaración
	 * 150000 => 49416.15
	 * 150001 => 4324325.43
	 * 150002 => 496546547416.75
	 */
	public static function detallesMultaFormal(array $array_declaraciones_multa, bool $consultar = false) : array{
		$devolver = [];

		for($i = 0; $i < count($array_declaraciones_multa); $i++){	
			$monto_for = 0.00;

			$multa_formal = SidcaiDeclaracionMulta::model()->findAll([
    			'select' => 'decl_mult_monto, decl_mult_fecha',
    			'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND mult_codigo_fk != :mult_codigo_fk',
    			'params' => [
    				':decl_codigo_fk' => $array_declaraciones_multa[$i],
    				':mult_habilitada' => TRUE,
    				':mult_codigo_fk' => 1
    			],
    			'order' => 'decl_mult_codigo_pk DESC'
    		]);

			if($multa_formal != null){
				foreach($multa_formal as $m){				
					if($consultar)
						$monto_for += $m->decl_mult_monto;
					else
						$monto_for += bcdiv(self::reconversion($m->decl_mult_fecha, $m->decl_mult_monto), '1', 2);
				}

				$devolver[$array_declaraciones_multa[$i]] = bcdiv($monto_for, '1', 2);
			}
		}

		return $devolver;
	}

	/**
	 * Obtiene el porcentaje de contribución de la empresa
	 */
	public static function porcentajeContribucion(int $id_ciiu) : string{
		$ciiu = SidcaiCiiu::model()->findByPk($id_ciiu);

		$devolver = "0.50";

		if($ciiu != null){
			$devolver = ($ciiu->ciiu_porcentaje_2010_priv == null) ? $ciiu->ciiu_porcentaje_2010 : $ciiu->ciiu_porcentaje_2010_priv;
		}

		return $devolver;
	}

	/**
	 * Devuelve TRUE si se requiere algo que solo sea cuando la empresa se encuentra durante el proceso de renovación.
	 */
	public static function mostrarRenovar(int $id_empresa): bool {
		$empresa = SidcaiAportante::model()->findByPk($id_empresa);
	
		$dia_cierre = $empresa->apor_diacierre;
		$mes_cierre = $empresa->apor_mescierre;
	
		$existe = SidcaiEjercicioFiscal::model()->find([
			'condition' => 'apor_codigo_fk = :apor_codigo_fk',
			'params' => [':apor_codigo_fk' => $id_empresa],
			'order' => 'ejercicio_fiscal_pk DESC',
		]);
	
		if ($existe != null) {
			$dia_cierre = $existe->apor_diacierre;
			$mes_cierre = $existe->apor_mescierre;
		}
	
		if ($mes_cierre < 10) {
			$mes_cierre = "0" . $mes_cierre;
		}
	
		$date = new DateTime("now", new DateTimeZone('America/Caracas'));
		$hoy_dia = $date->format('d');
		$hoy_mes = $date->format('m');
		$hoy_anio = $date->format('Y');
		$hoy = $date->format('Y-m-d');
	
		$declaracion = SidcaiDeclaracioncti::model()->find([
			'select' => 'esta_codigo_fk, decl_fechadeclaracion, decl_fechafin_base',
			'condition' => 'apor_codigo_fk = :apor_codigo_fk AND (esta_codigo_fk IN (:estatus1, :estatus2, :estatus3, :estatus4, :estatus5, :estatus6, :estatus7))',
			'params' => [
				':apor_codigo_fk' => $id_empresa,
				':estatus1' => 1003,
				':estatus2' => 1004,
				':estatus3' => 1001,
				':estatus4' => 1006,
				':estatus5' => 1010,
				':estatus6' => 1011,
				':estatus7' => 1008,
			],
			'order' => 'decl_codigo_pk DESC'
		]);

		/*
		echo '<pre>';
		print_r($declaracion);
		echo '<pre>';
		die();*/
/*
		(
            [esta_codigo_fk] => 1003
            [decl_fechadeclaracion] => 2025-01-29
            [decl_fechafin_base] => 2024-12-31
        )
*/

	
		// Inicializar $anio_declaracion para evitar errores
		$anio_declaracion = [0, 0, 0]; // Año, mes, día por defecto
	
		if ($declaracion != null) {

			//echo "siii";die();
			if ($declaracion->esta_codigo_fk == 1003 || $declaracion->esta_codigo_fk == 1004) {
				$anio_declaracion = explode("-", $declaracion->decl_fechadeclaracion);
				$fecha_fin_base = explode("-", $declaracion->decl_fechafin_base);

				//echo  $hoy;
				//echo $declaracion->decl_fechafin_base;die();
	
				if (strtotime($hoy) > strtotime($declaracion->decl_fechafin_base)) {
					//if (strtotime($hoy) > strtotime($declaracion->decl_fechafin_base . '+1 year')) {

					return true;
				}
			}
		}
	
		$declaracionesmensualesUltima = SidcaiDeclaracioncti::model()->find([
			'condition' => "apor_codigo_fk = :apor_codigo_fk AND esta_codigo_fk IN (1003, 1004) AND decl_tipodeclaracion = 'M'",
			'params' => [':apor_codigo_fk' => Yii::app()->user->id],
			'order' => 'decl_fechadeclaracion DESC',
		]);
	
		$cad2 = "";
	
		if ($declaracionesmensualesUltima != null) {
			$aniom = $declaracionesmensualesUltima["decl_fechafin_base"];
			$datetimem = new DateTime($aniom);
			$yearm = $datetimem->format('Y');
			$cad2 = $anio_declaracion[0] . "-" . $anio_declaracion[1] . "-" . $anio_declaracion[2];
		} else {
			$declaracionesAnualesUltima = SidcaiDeclaracioncti::model()->find([
				'condition' => "apor_codigo_fk = :apor_codigo_fk AND esta_codigo_fk IN (1003, 1004) AND decl_tipodeclaracion = 'O'",
				'params' => [':apor_codigo_fk' => Yii::app()->user->id],
				'order' => 'decl_fechadeclaracion DESC',
			]);
	
			if ($declaracionesAnualesUltima != null) {
				$anioc = $declaracionesAnualesUltima["decl_fechafin_base"];
				$datetimea = new DateTime($anioc);
				$yeara = $datetimea->format('Y');
				$cad2 = $anio_declaracion[0] . "-" . $anio_declaracion[1] . "-" . $anio_declaracion[2];
			}
		}
	
		$recaudo = SidcaiRecaudo::model()->find([
			'condition' => "apor_codigo_fk = :apor_codigo AND tipo_codigo_fk = :tipo_documento",
			'params' => [':tipo_documento' => 3, ':apor_codigo' => Yii::app()->user->id],
			'order' => 'reca_codigo_pk DESC',
		]);


		//echo $rutaArchivo;die();
		if ($recaudo !== null) {
			$rutaArchivo = $recaudo['reca_direccion'];
		
			if (preg_match('/\d{4}-\d{2}-\d{2}/', $rutaArchivo, $matches)) {
				$fechaArchivo = $matches[0];
				$fechaArchivoCompleta = $fechaArchivo;
				$fechaReferencia = $cad2;
		
				if (strtotime($fechaArchivoCompleta) < strtotime($fechaReferencia)) {
					return true;
				}
			}
		}
			// Handle the case where $recaudo is null or 'reca_direccion' is not set
			// For example, you could log an error or return false
			return false;
		
	
		
	}


	public static function mostrarRenovarVerificacion(int $id_empresa) : bool{
		$empresa = SidcaiAportante::model()->findByPk($id_empresa);

        $dia_cierre = $empresa->apor_diacierre;
        $mes_cierre = $empresa->apor_mescierre;

        // 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_empresa),
                'order' => 'ejercicio_fiscal_pk DESC',
            )
        );

        // Sí el aportante ha cambiado su Ejercicio Fiscal usará los datos del "SidcaiEjercicioFiscal".
        if($existe != null){
            $dia_cierre = $existe->apor_diacierre;
            $mes_cierre = $existe->apor_mescierre;
        }

        if($mes_cierre < 10){
        	$mes_cierre = "0".$mes_cierre;
        }

        $date = new DateTime("now", new DateTimeZone('America/Caracas'));
        $hoy_dia = $date->format('d');
        $hoy_mes = $date->format('m');
        $hoy_anio = $date->format('Y');
        $hoy = $date->format('Y-m-d');

        // Se busca la última declaración 
        $declaracion = SidcaiDeclaracioncti::model()->find([
            'select' => 'esta_codigo_fk, decl_fechadeclaracion, decl_fechafin_base',
            'condition' => 'apor_codigo_fk = :apor_codigo_fk AND (esta_codigo_fk = :estatus1  OR esta_codigo_fk = :estatus2 OR esta_codigo_fk = :estatus3 OR esta_codigo_fk = :estatus4 OR esta_codigo_fk = :estatus5 OR esta_codigo_fk = :estatus6 OR esta_codigo_fk = :estatus7)',
            'params' => [
            	':apor_codigo_fk' => $id_empresa,
            	':estatus1' => 1003,
            	':estatus2' => 1004,
            	':estatus3' => 1001,
            	':estatus4' => 1006,
            	':estatus5' => 1010,
            	':estatus6' => 1011,
            	':estatus7' => 1008,
            ],
            'order' => 'decl_codigo_pk DESC'
		]);

	/*	echo '<pre>';
		print_r($declaracion);
		echo '<pre>';
		die();*/
		


        if($declaracion != null){
        	if($declaracion->esta_codigo_fk == 1003 || $declaracion->esta_codigo_fk == 1004){
				//echo "1";die();
	        	// Si el año actual es el mismo que la declaración y el día y mes del cierre fiscal es igual que no muestre "Renovar"
	        	$anio_declaracion 	= explode("-", $declaracion->decl_fechadeclaracion);
				$fecha_fin_base 	= explode("-", $declaracion->decl_fechafin_base);
	        	/*if(intval($hoy_anio) > intval($anio_declaracion[0])){
	    			if(strtotime($hoy) > strtotime($declaracion->decl_fechadeclaracion)){
	        			if(strtotime($hoy) > strtotime($hoy_anio."-".$mes_cierre."-".$dia_cierre)){
	        				return true;
	        			}else{
	        				return false;
						}
						if(strtotime($hoy) > strtotime($declaracion->decl_fechafin_base.'+1 year')){
	        				return true;
	        			}else{
	        				return false;
						}
						
	        		}else{
	        			return false;
					}*/
					if(strtotime($hoy) > strtotime($declaracion->decl_fechafin_base.'+1 year')){
						return true;
					}
	        	/*}else
	        		return true;*/
        	}
        }

        return false;
	}

	
	

	/**
	 * Devuelve los datos de las multas formales seleccionadas
	 * @return array
	 */
	public static function multasFormalesSeleccionadas(int $id_declaracion) : array{
		$datos = [];

		$multas = [];

		// Se busca todas las multas formales seleccionadas
		$multas_formales = SidcaiDeclaracionMulta::model()->findAll([
			'select' => 'mult_codigo_fk',
			'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND mult_codigo_fk != :mult_codigo_fk',
			'params' => [
				':decl_codigo_fk' => $id_declaracion,
				':mult_habilitada' => TRUE,
				':mult_codigo_fk' => 1
			]
		]);

		foreach($multas_formales as $m){
			array_push($multas, $m->mult_codigo_fk);
		}
		
		$multa_mayor = 0;
		$id_mayor = NULL;

		// Se obtiene el id de la multa con mayor monto.
		if(count($multas) > 1){
			for($i = 0; $i < count($multas); $i++){
				$multa = SidcaiMulta::model()->findByPk($multas[$i]);

				if($multa != null){
					if($multa_mayor < $multa->mult_unidadestributarias){
						$multa_mayor = $multa->mult_unidadestributarias;
						$id_mayor = $multa->mult_codigo_pk;
					}
				}
			}
		}


		if(count($multas) == 0 || empty($multas)){
			$datos['tiene_multas'] = false;
		}else{
			$datos['tiene_multas'] = true;

			$cantidad_ut 	= 0;
			$cantidad_ut_82 = 0;

			for($i = 0; $i < count($multas); $i++){
				$mult = SidcaiMulta::model()->findByPk($multas[$i]);

				$detalles_multa = [];

				if($mult != null){
					$valor_unidad_tributaria = $mult->mult_unidadestributarias;

					$detalles_multa['ley'] = $mult->mult_ley;
					$detalles_multa['ut'] = $mult->mult_unidadestributarias;

					if($id_mayor != NULL){
						if($id_mayor == $multas[$i]){
							$art82 = $valor_unidad_tributaria;
							$detalles_multa['art82'] = $mult->mult_unidadestributarias; // Art.82
						}else{
							$art82 = ($mult->mult_unidadestributarias / 2);
							$detalles_multa['art82'] = $art82; // Art.82
						}
					}else{
						$art82 = $valor_unidad_tributaria;
						$detalles_multa['art82'] =$mult->mult_unidadestributarias; // Art.82
					}

					$detalles_multa['descripcion'] = $mult->mult_descripcion;
					$detalles_multa['ley'] = $mult->mult_ley;
					$detalles_multa['ley'] = $mult->mult_ley;


					$cantidad_ut 	= $cantidad_ut + $mult->mult_unidadestributarias;
					$cantidad_ut_82 = $cantidad_ut_82 + $art82;
				}

				$datos['multas_seleccionadas'][] = $detalles_multa;
			}

			$ut_actual = SidcaiUnidadtributaria::model()->find([
				'order' => 'unid_codigo_pk DESC',
				'limit' => 1
			]);

			$total_multa = $ut_actual->unid_valor * $cantidad_ut_82;

			$datos['valor_ut'] 		= $ut_actual->unid_valor;
			$datos['cantidad_ut'] 	= $cantidad_ut;
			$datos['cantidad_ut_82'] = $cantidad_ut_82;
			$datos['total_multa'] = $total_multa;
		}

		
		return $datos;
	}

	/**
	 * Devuelve la tabla de las multas formales para el acta de reparo que emite fiscalización
	 */
	public static function tablaMultasFormalesActa(int $id_declaracion) : string{
		$multa = self::multasFormalesSeleccionadas($id_declaracion);

		$tabla = "";

		if($multa['tiene_multas']){
			for($i = 0; $i < count($multa['multas_seleccionadas']); $i++){
				$m = $multa['multas_seleccionadas'][$i];

				$tabla .= '<tr>';
				$tabla .= '<td style="text-align: justify">'.$m['descripcion'].'</td>';
				$tabla .= '<td>'.$m['ley'].'</td>';
				$tabla .= '<td>'.number_format($m['ut'], 0, ',', '.').'</td>';
				$tabla .= '<td>'.number_format($m['art82'], 0, ',', '.').'</td>';
				$tabla .= '</tr>';
			}

			$date = new DateTime("now", new DateTimeZone('America/Caracas'));
			$hoy = $date->format('Y-m-d');

			$ut_actual = SidcaiUnidadtributaria::model()->find([
				'order' => 'unid_codigo_pk DESC',
				'limit' => 1
			]);

			$total_multa = $ut_actual->unid_valor * $multa['cantidad_ut_82'];

			$valor_ut 	 = self::obtenerMoneda($hoy)." ".number_format($ut_actual->unid_valor, 2, ",", ".");
			$total_multa = self::obtenerMoneda($hoy)." ". number_format($total_multa, 2, ",", ".");

			$tabla .= "<tr>";
			$tabla .= "<td colspan='2' style='text-align: right'><b>TOTALES</b></td>";
			$tabla .= "<td><b>".number_format($multa['cantidad_ut'], 0, ",", ".") ." U.T</b></td>";
			$tabla .= "<td><b>".number_format($multa['cantidad_ut_82'], 0, ",", ".") ." U.T</b></td>";
			$tabla .= "</tr>";
		}else{
			$tabla = "<tr><td colspan='4'><center>No hay multas seleccionadas.</center></td></tr>";
		}

		return $tabla;
	}

	/**
	 * Reemplaza caracteres especiales para ser mostrado en PDF
	 */
	public static function reemplazar_caracteres(string $texto) : string{
        $caracteres_reemplazar = ["&AMP;" => "&", "&QUOT;" => '"'];

        foreach($caracteres_reemplazar as $key => $value){
        	$texto = str_replace($key, $value, $texto);
        }

        return $texto;
	}


	/**
	 * Fecha 
	 */
	public static function obtenerFecha(string $formato = 'Y-m-d') : string {
		$date = new DateTime("now", new DateTimeZone('America/Caracas'));
		$hoy = $date->format($formato);
		return $hoy;
	}

	/**
	 * Cantidad de años que la empresa tiene sin declarar.
	 */
	public static function datos_empresa(int $id_empresa) : array{
		$empresa = SidcaiAportante::model()->findByPk($id_empresa);

		// Datos a devolver.
		$datos = [];

		// Guarda el último peirodo Gravable de la empresa.
		$ultimo_periodo_gravable = null;

		// $fce = Fecha creacion empresa
		$fce = explode("-", $empresa->apor_fechacreacionempresa);
		$fced = $fce[2]; // Día
		$fcem = $fce[1]; // Mes
		$fcea = $fce[0]; // Año

		// Fecha minimo para pedir el periodo gravable;
		// Es decir, desde este año vas a pedir hasta el año actual.
		$fecha_desde = null;

		// Fecha.
		$date = new DateTime("now", new DateTimeZone('America/Caracas'));
		$hoy = $date->format('Y-m-d');
		$hoy_anio = $date->format('Y');


		/*******	Se busca la última declaración realizada por la empresa.	*******/
		$ultima_declaracion = SidcaiDeclaracioncti::model()->find(
			array(
				'condition' => "apor_codigo_fk = :apor_codigo_fk AND (esta_codigo_fk != :estatus_1 AND esta_codigo_fk != :estatus_2) AND decl_tipodeclaracion != 'M'",
				'params' => [
					':apor_codigo_fk' => $id_empresa,
					':estatus_1' => 1005,
					':estatus_2' => 1009
				],
				'order' => 'decl_fechainicio_base DESC',
				'limit' => 1,
			)
		);

		$ultima_fecha_declaracion = null;

		if($ultima_declaracion == null){// Si la empresa no tiene declaraciones en la base de datos actual.
			$rif = $empresa->apor_rif;

			// Se busca la Empresa en la anterior base de datos por medio de su RIF
			$sql = "SELECT apor_codigo_pk FROM sidcai_aportante WHERE apor_rif = :apor_rif AND (esta_codigoestatus_fk = 2003 OR esta_codigoestatus_fk = 1001)";
			$comando = Yii::app()->db2->createCommand($sql);
			$comando->bindParam(":apor_rif", $rif);
			$empresa_historico = $comando->queryRow();

			// Si el registro devuelve datos significa que la Empresa ya estaba registrada ante FONACIT en BD_HISTORICO.
			if($comando->queryRow() != null){
				// Se busca la útlima declaracion que tenga la Empresa.
				$sql = "SELECT decl_fechadeclaracion, decl_fechainicio_base, decl_fechafin_base, decl_fechainicio, decl_fechafin FROM sidcai_declaracioncti WHERE apor_codigo_fk = :apor_codigo_fk AND (esta_codigo_fk != 1005 AND esta_codigo_fk!=1001) ORDER BY decl_fechainicio_base DESC LIMIT 1";
				$comando = Yii::app()->db2->createCommand($sql);
				$comando->bindParam(':apor_codigo_fk', $empresa_historico['apor_codigo_pk']);
				$declaraciones = $comando->queryRow();

				// Si ingresa al IF es que tiene declaraciones en BD_HISTORICO.
				if($declaraciones != null){
					$ultimo_periodo_gravable['fecha_inicio_gravable'] = $declaraciones['decl_fechainicio_base'];
					$ultimo_periodo_gravable['fecha_fin_gravable'] 	  = $declaraciones['decl_fechafin_base'];
					$ultima_fecha_declaracion = $declaraciones['decl_fechadeclaracion'];
				}
			}
		}else{
			$ultimo_periodo_gravable['fecha_inicio_gravable'] = $ultima_declaracion->decl_fechainicio_base;
			$ultimo_periodo_gravable['fecha_fin_gravable'] 	  = $ultima_declaracion->decl_fechafin_base;
			$ultima_fecha_declaracion = $ultima_declaracion->decl_fechadeclaracion;
		}

		/* se calcula la edad de la ultima declaración */
        $date = date("Y-m-d", strtotime($ultimo_periodo_gravable['fecha_fin_gravable']));

		$edad_ultima_declaracion = new DateTime($date);
		
		$dateTimeHoy = new DateTime();
		$edad_ultima_declaracion = $dateTimeHoy->diff($edad_ultima_declaracion);
		$edad_ultima_declaracion = $edad_ultima_declaracion->y;
	
		if($edad_ultima_declaracion > 40) $edad_ultima_declaracion = 40;
		
		/*************		Fin de buscar la última declaración de la empresa	**************/

		// Pedir los últimos 3 años, siempre y cuando no tengas declaraciones atrasadas y su fecha constitutiva se mayor a los últimos 3 años
		$periodo_desde = date("Y",strtotime($hoy." -$edad_ultima_declaracion year")); 

		$inicio_perido_gravable = "";
		$fin_perido_gravable 	= "";

		$periodos_gravables = [];

		// Mes y día de cierre del periodo gravable.
		$modificacion_ejercicio_fiscal = SidcaiEjercicioFiscal::model()->find([
			'select' => 'apor_diacierre, apor_mescierre',
			'condition' => 'apor_codigo_fk = :apor_codigo_fk',
			'params' => [
				':apor_codigo_fk' => $id_empresa
			],
			'order' => 'ejercicio_fiscal_pk DESC'
		]);

		// Sí existe una modificación del ejercicio fiscal por parte de la empresa.
		if($modificacion_ejercicio_fiscal != null){
			$mes_cierre = $modificacion_ejercicio_fiscal->apor_mescierre;
			$dia_cierre = $modificacion_ejercicio_fiscal->apor_diacierre;
		}else{
			$mes_cierre = $empresa->apor_mescierre;
			$dia_cierre = $empresa->apor_diacierre;
		}

		if($mes_cierre < 10)
			$mes_cierre = "0".$mes_cierre;

		if($dia_cierre < 10)
			$dia_cierre = "0".$dia_cierre;

		if($ultima_fecha_declaracion != null){
			$separar_ultimo_periodo_gravable_inicio = explode("-", $ultimo_periodo_gravable['fecha_inicio_gravable']);
			$separar_ultimo_periodo_gravable_fin 	= explode("-", $ultimo_periodo_gravable['fecha_fin_gravable']);

			$anio_inicio_periodo 	= $separar_ultimo_periodo_gravable_inicio[0];
			$anio_fin_periodo 		= $separar_ultimo_periodo_gravable_fin[0];
		}else{
			// Pedir los últimos 4 años, siempre y cuando no tengas declaraciones atrasadas y su fecha constitutiva se mayor a los últimos 4 años
			$periodo_desde = date("Y",strtotime($hoy." -$edad_ultima_declaracion year")); 

			if($fcea < $periodo_desde){
				if($mes_cierre <= "06")
					$anio_fin_periodo = $hoy_anio - 4;
				else
					$anio_fin_periodo = $hoy_anio - 5;
			}
			else{
				$anio_fin_periodo = $hoy_anio - $fcea;
				$anio_fin_periodo = ($hoy_anio - $anio_fin_periodo) - 1;
			}
		}

		// $date2 = new DateTime("2022-04-01", new DateTimeZone('America/Caracas'));
		// $fecha_nueva_ley = $date2->format('Y-m-d');

		for($i = 1; $i <= $edad_ultima_declaracion; $i++){
			$fin_perido_gravable = $anio_fin_periodo + $i."-".$mes_cierre."-".$dia_cierre;
			$inicio_perido_gravable = date("Y-m-d",strtotime($fin_perido_gravable." -1 year +1 day"));

			if(date('Y',strtotime($fin_perido_gravable)) <= 2015)
				continue;

			if(strtotime($fin_perido_gravable) > strtotime($hoy))
				continue;

			// if(strtotime($inicio_perido_gravable) >= strtotime($fecha_nueva_ley))
			// 	continue;

			if(strtotime($empresa->apor_fechacreacionempresa) > strtotime($inicio_perido_gravable))
				continue;

			// Obtener UT 
			$ut 		= FuncionesController::obtenerUT($inicio_perido_gravable, $fin_perido_gravable);
			$moneda_ut 	= FuncionesController::obtenerMoneda($fin_perido_gravable);
			$ut 		= "Valor UT: ".$moneda_ut." ".number_format($ut, 2, ",", ".");

			$periodos_gravables[] = [
				'inicio_periodo_gravable'	=> $inicio_perido_gravable,
				'fin_periodo_gravable' 		=> $fin_perido_gravable,
				'ut' 						=> $ut,
			];	
		}

		$datos = [
			'fecha_desde' 		 => (int) $fecha_desde,
			'anios_sin_declarar' => count($periodos_gravables),
			'periodos_gravables' => array_reverse($periodos_gravables),
		];

		return $datos;
	}

   
    //LM
	public static function checkPathAndFile($directory) {
	
		if (is_dir($directory)) {
			//echo "La carpeta '$directory' existe.\n";
			return "si";
		} else {
			//echo "La carpeta '$directory' no existe.\n";
			return "no";
		}

	}

	public static function checkPathAndFile2($directory) {
	
		if (file_exists($directory)) {
			//echo "La carpeta '$directory' existe.\n";
			return "si";
		} else {
			//echo "La carpeta '$directory' no existe.\n";
			return "no";
		}

	}

	public static function checkPathAndFile3($filePath) {
		if (is_file($filePath)) {
			// El archivo existe
			return "si";
		} else {
			// El archivo no existe
			return "no";
		}
	}
	

	public static function directoryExists($remoteDir)
    {
		$ftpServer =   Yii::app()->params['FTPSERVER'];
		$ftpUsername = Yii::app()->params['FTPUSERNAME'];
		$ftpPassword = Yii::app()->params['FTPPASSWORD'];
		$port =        Yii::app()->params['PORT'];

		try {
			
			$connection = ssh2_connect($ftpServer, $port);


			if (!$connection) {
				throw new Exception('No se puede conectar al servidor remoto.');
			}

			if (!ssh2_auth_password($connection,$ftpUsername, $ftpPassword)) {
				throw new Exception('Falló la autenticación.');
			}

			$sftp = ssh2_sftp($connection);
			if (!$sftp) {
				throw new Exception('No se pudo inicializar el subsistema SFTP.');
			}

			$verificar = self::directorySshExists($remoteDir,$sftp);
			
			if ($verificar) {
				//echo "¡El directorio existe!";
				return "si";
			} else {
				//echo "El directorio no existe.";
				return "no";
			}
		} catch (Exception $e) {
			echo "Ocurrió un error: " . $e->getMessage();
		}
    }

	public static function directoryExists2($remoteDir)
    {
		$ftpServer =   Yii::app()->params['FTPSERVER'];
		$ftpUsername = Yii::app()->params['FTPUSERNAME'];
		$ftpPassword = Yii::app()->params['FTPPASSWORD'];
		$port =        Yii::app()->params['PORT'];

		try {
			
			$connection = ssh2_connect($ftpServer, $port);


			if (!$connection) {
				throw new Exception('No se puede conectar al servidor remoto.');
			}

			if (!ssh2_auth_password($connection,$ftpUsername, $ftpPassword)) {
				throw new Exception('Falló la autenticación.');
			}

			$sftp = ssh2_sftp($connection);
			if (!$sftp) {
				throw new Exception('No se pudo inicializar el subsistema SFTP.');
			}

			$verificar = self::directorySshExists2($remoteDir,$sftp);
			
			if ($verificar) {
				//echo "¡El directorio existe!";
				return "si";
			} else {
				//echo "El directorio no existe.";
				return "no";
			}
		} catch (Exception $e) {
			echo "Ocurrió un error: " . $e->getMessage();
		}
    }

	public static function directorySshExists($remoteDir,$sftp)
    {
        $dirPath = "ssh2.sftp://{$sftp}{$remoteDir}";

        return is_dir($dirPath);
    }

	public static function directorySshExists2($remoteDir,$sftp)
    {
        $dirPath = "ssh2.sftp://{$sftp}{$remoteDir}";

        return file_exists($dirPath);
    }


	public static function crearCarpetaSsh2($ruta)
{
    $ftpServer   = Yii::app()->params['FTPSERVER'];
    $ftpUsername = Yii::app()->params['FTPUSERNAME'];
    $ftpPassword = Yii::app()->params['FTPPASSWORD'];
    $port        = Yii::app()->params['PORT'];

    try {
        // Conexión al servidor SSH
        $connection = ssh2_connect($ftpServer, $port);
        if (!$connection) {
            throw new Exception('No se puede conectar al servidor remoto.');
        }

        // Autenticación
        if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
            throw new Exception('Falló la autenticación.');
        }

        // Crear la carpeta
        $command = " mkdir -p " . escapeshellarg($ruta);
        $output = ssh2_exec($connection, $command);
        
        // Verificar la salida
        stream_set_blocking($output, true);
        $result = stream_get_contents($output);
        
        // Comprobar si el comando se ejecutó correctamente
        if ($result === false) {
            throw new Exception('No se pudo crear el directorio remoto: ' . $ruta);
        }

		// Esperar a que el comando termine
		fclose($output);

	// Cambiar el grupo del directorio remotamente (si es necesario)
    // Por ejemplo, cambiar el grupo al grupo 'www-data' para que sea accesible por el servidor web
    $command = "echo '$ftpPassword' | sudo -S chown -R www-data: " . escapeshellarg($ruta);
    $output = ssh2_exec($connection, $command);
    stream_set_blocking($output, true);
    $result = stream_get_contents($output);

    if ($result === false) {
        throw new Exception('No se pudo cambiar el grupo del directorio: ' . $ruta);
    }

    // Esperar a que el comando termine
    fclose($output);

        // Establecer permisos 777 al directorio (lectura, escritura y ejecución para todos)
    $chmodCommand = "echo '$ftpPassword' | sudo -S chmod -R 777 " . escapeshellarg($ruta);
    $output = ssh2_exec($connection, $chmodCommand);
    stream_set_blocking($output, true);
    $result = stream_get_contents($output);

    if ($result === false) {
        throw new Exception('No se pudo cambiar los permisos del directorio: ' . $ruta);
    }

    // Esperar a que el comando termine
    fclose($output);

    return "si"; // Carpeta creada exitosamente

    // Cerrar la conexión SSH
    ssh2_disconnect($connection);

       // return "si"; // Carpeta creada exitosamente

    } catch (Exception $e) {
        // Manejo de errores
        return "no: " . $e->getMessage();
    }
}


	public function cambiarGrupoArchivo($remoteFilePath)
{
    // Credenciales del servidor SSH
    $ftpServer = Yii::app()->params['FTPSERVER'];
    $ftpUsername = Yii::app()->params['FTPUSERNAME'];
    $ftpPassword = Yii::app()->params['FTPPASSWORD'];
    $port = Yii::app()->params['PORT'];

    // Conectar al servidor SSH
    $connection = ssh2_connect($ftpServer, $port);
    if (!$connection) {
        die('No se pudo establecer la conexión SSH.');
    }

    // Autenticarse en el servidor SSH
    if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
        die('Error al autenticar con el servidor SSH.');
    }

    // Cambiar el grupo del archivo a www-data
    //$command = "sudo chown www-data:www-data -R '$remoteFilePath'";

	$command = "sudo chown www-data:www-data -R " . escapeshellarg($remoteFilePath);



    // Ejecutar el comando en el servidor remoto
    $stream = ssh2_exec($connection, $command);
    if (!$stream) {
        die('Error al ejecutar el comando chown.');
    }

    // Capturar la salida del comando (si es necesario)
    stream_set_blocking($stream, true);
    $output = stream_get_contents($stream);
    fclose($stream);

    // Verificar si hubo algún error durante la ejecución del comando
    if (!empty($output)) {
        //echo "Resultado de la ejecución del comando: " . $output;
    } else {
        //echo "El grupo del archivo ha sido cambiado exitosamente a www-data.";
    }

    // Cerrar la conexión SSH
    ssh2_disconnect($connection);
}

public function cambiarPermiso($remoteFilePath,$permiso)
{
    // Credenciales del servidor SSH
    $ftpServer = Yii::app()->params['FTPSERVER'];
    $ftpUsername = Yii::app()->params['FTPUSERNAME'];
    $ftpPassword = Yii::app()->params['FTPPASSWORD'];
    $port = Yii::app()->params['PORT'];

    // Conectar al servidor SSH
    $connection = ssh2_connect($ftpServer, $port);
    if (!$connection) {
        die('No se pudo establecer la conexión SSH.');
    }

    // Autenticarse en el servidor SSH
    if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
        die('Error al autenticar con el servidor SSH.');
    }

    // Cambiar el grupo del archivo a www-data
    $command = "echo $ftpPassword | sudo chmod $permiso -R '$remoteFilePath'";

    // Ejecutar el comando en el servidor remoto
    $stream = ssh2_exec($connection, $command);
    if (!$stream) {
        die('Error al ejecutar el comando chown.');
    }

    // Capturar la salida del comando (si es necesario)
    stream_set_blocking($stream, true);
    $output = stream_get_contents($stream);
    fclose($stream);

    // Verificar si hubo algún error durante la ejecución del comando
    if (!empty($output)) {
        //echo "Resultado de la ejecución del comando: " . $output;
    } else {
        //echo "El grupo del archivo ha sido cambiado exitosamente a www-data.";
    }

    // Cerrar la conexión SSH
    ssh2_disconnect($connection);
}



public static function crearArchivoSsh2($tempFilePath, $ruta, $ruta_aportante)
{

	//print_r($tempFilePath);
	//echo "<br>";
	//print_r($ruta);die;
    // Parámetros FTP/SSH
    $ftpServer   = Yii::app()->params['FTPSERVER'];
    $ftpUsername = Yii::app()->params['FTPUSERNAME'];
    $ftpPassword = Yii::app()->params['FTPPASSWORD'];
    $port        = Yii::app()->params['PORT'];

    // Permisos y grupo
    $permisos = '775'; // Permisos deseados
	$grupo = 'www-data'; // Grupo deseado
    $propietario = 'www-data'; // Propietario deseado

    try {
        // Conectar al servidor SSH
        $connection = ssh2_connect($ftpServer, $port);
        if (!$connection) {
            throw new Exception('No se puede conectar al servidor remoto.');
        }

        // Autenticación SSH
        if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
            throw new Exception('Falló la autenticación.');
        }

        // Verificar si el archivo temporal existe antes de enviar
        if (!file_exists($tempFilePath)) {
            throw new Exception('El archivo temporal no existe.');
        }

        
        // Transferir el archivo al servidor remoto usando SCP
		if (ssh2_scp_send($connection, $tempFilePath, $ruta)) {
            // Eliminar el archivo temporal
            unlink($tempFilePath);

            // Cambiar permisos del archivo (chmod) usando sudo
            $chmodCommand = "echo '$ftpPassword' | sudo -S chmod $permisos " . escapeshellarg($ruta);
            $output = ssh2_exec($connection, $chmodCommand);
            stream_set_blocking($output, true);
            $result = stream_get_contents($output);
            fclose($output);
            if ($result === false) {
                throw new Exception('No se pudieron cambiar los permisos del archivo: ' . $ruta);
            }

            // Cambiar propietario y grupo del archivo (chown) usando sudo
            $chownCommand = "echo '$ftpPassword' | sudo -S chown $propietario:$grupo " . escapeshellarg($ruta);
            $output = ssh2_exec($connection, $chownCommand);
            stream_set_blocking($output, true);
            $result = stream_get_contents($output);
            fclose($output);
            if ($result === false) {
                throw new Exception('No se pudieron cambiar el propietario y el grupo del archivo: ' . $ruta);
            }

            // Retornar éxito
			return "si";
            //return "Archivo subido y permisos configurados correctamente.";
        } else {
            throw new Exception('Falló la transferencia del archivo.');
        }
    } catch (Exception $e) {
        // Manejo de errores
		return "no";
        //return "Error: " . $e->getMessage();
    } finally {
        // Cerrar la conexión SSH
        if (isset($connection)) {
            ssh2_disconnect($connection);
        }
    }
}




public static function cambiarGrupoArchivossh2($rutaArchivo, $grupo = 'www-data')
{
    $ftpServer   = Yii::app()->params['FTPSERVER'];
    $ftpUsername = Yii::app()->params['FTPUSERNAME'];
    $ftpPassword = Yii::app()->params['FTPPASSWORD'];
    $port        = Yii::app()->params['PORT'];

    try {
        $connection = ssh2_connect($ftpServer, $port);
        if (!$connection) {
            throw new Exception('No se puede conectar al servidor remoto.');
        }

        if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
            throw new Exception('Falló la autenticación.');
        }

        // Ejecutar el comando chgrp para cambiar el grupo del archivo
        $command = "sudo chgrp $grupo $rutaArchivo";
        $stream = ssh2_exec($connection, $command);
        stream_set_blocking($stream, true);
        $output = stream_get_contents($stream);
        fclose($stream);

        if ($output === false) {
            throw new Exception('Falló al cambiar el grupo del archivo.');
        }
    } catch (Exception $e) {
        return "Error: " . $e->getMessage();
    }
}

public static function cambiarPropietarioYGrupoSsh2($rutaArchivo, $propietarioGrupo = 'www-data:www-data')
{
    $ftpServer   = Yii::app()->params['FTPSERVER'];
    $ftpUsername = Yii::app()->params['FTPUSERNAME'];
    $ftpPassword = Yii::app()->params['FTPPASSWORD'];
    $port        = Yii::app()->params['PORT'];

    try {
        $connection = ssh2_connect($ftpServer, $port);
        if (!$connection) {
            throw new Exception('No se puede conectar al servidor remoto.');
        }

        if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
            throw new Exception('Falló la autenticación.');
        }

        // Ejecutar el comando chown para cambiar el propietario y grupo del archivo
        $command = "sudo chown $propietarioGrupo $rutaArchivo";
        $stream = ssh2_exec($connection, $command);
        stream_set_blocking($stream, true);
        $output = stream_get_contents($stream);
        fclose($stream);

        if ($output === false) {
            throw new Exception('Falló al cambiar el propietario y grupo del archivo.');
        }
    } catch (Exception $e) {
        return "Error: " . $e->getMessage();
    }
}


public static function cambiarPermisoSSh2($rutaArchivo, $permisos = '777')
{
    $ftpServer   = Yii::app()->params['FTPSERVER'];
    $ftpUsername = Yii::app()->params['FTPUSERNAME'];
    $ftpPassword = Yii::app()->params['FTPPASSWORD'];
    $port        = Yii::app()->params['PORT'];

    try {
        $connection = ssh2_connect($ftpServer, $port);
        if (!$connection) {
            throw new Exception('No se puede conectar al servidor remoto.');
        }

        if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
            throw new Exception('Falló la autenticación.');
        }

        // Ejecutar el comando chmod para cambiar los permisos del archivo
        $command = "sudo chmod $permisos $rutaArchivo";
        $stream = ssh2_exec($connection, $command);
        stream_set_blocking($stream, true);
        $output = stream_get_contents($stream);
        fclose($stream);

        if ($output === false) {
            throw new Exception('Falló al cambiar los permisos del archivo.');
        }
    } catch (Exception $e) {
        return "Error: " . $e->getMessage();
    }
}


    public static function Descargar($archivo)
    {
    	$ftpServer =   Yii::app()->params['FTPSERVER'];
			$ftpUsername = Yii::app()->params['FTPUSERNAME'];
			$ftpPassword = Yii::app()->params['FTPPASSWORD'];
			$port =        Yii::app()->params['PORT'];

        $connection = ssh2_connect($ftpServer, $port);
        ssh2_auth_password($connection, $ftpUsername, $ftpPassword);
        
        $sftp = ssh2_sftp($connection);
        $remoteFile =  Yii::app()->params['REMOTESIS'].$archivo;
        $localFile = '/var/local/file.jpg';
        
        $stream = fopen("ssh2.sftp://$sftp$remoteFile", 'r');
        $contents = stream_get_contents($stream);
        file_put_contents($localFile, $contents);
        fclose($stream);
        
        $url = Yii::setPathOfAlias('webroot') . $archivo;
        
        return  $url;
    }

	public function actionServirImagen($archivo)
    {
        // Datos de conexión SSH
        $ftpServer =   Yii::app()->params['FTPSERVER'];
		$ftpUsername = Yii::app()->params['FTPUSERNAME'];
		$ftpPassword = Yii::app()->params['FTPPASSWORD'];
		$port =        Yii::app()->params['PORT'];

    
        // Ruta del archivo remoto
        $remoteFile = Yii::app()->params['REMOTESIS'].$archivo;
		//print_r($remoteFile);die();
        
        // Establece la conexión SSH
        $connection = ssh2_connect($ftpServer, $port);
        
        
        if (ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
            // Abrir el archivo remoto para lectura
            $stream = ssh2_exec($connection, "cat $remoteFile");
            stream_set_blocking($stream, true);
            
            // Obtener el contenido de la imagen
            $imageContent = stream_get_contents($stream);
            
            // Cerrar la conexión
            fclose($stream);
            
            // Mostrar la imagen
            header('Content-Type: image/jpeg'); // Cambiar si es otro tipo de imagen
            echo $imageContent;
            exit;
        } else {
            Yii::$app->session->setFlash('error', 'Error de autenticación SSH.');
        }
        
        // En caso de error redirige o muestra un mensaje
        
    }


	public function DescargarFile($archivo)
	{
		// Configuración de conexión
		$ftpServer = Yii::app()->params['FTPSERVER'];
		$ftpUsername = Yii::app()->params['FTPUSERNAME'];
		$ftpPassword = Yii::app()->params['FTPPASSWORD'];
		$port = Yii::app()->params['PORT'];
	
		// Ruta del archivo en el servidor remoto
		$remoteFile = Yii::app()->params['REMOTESIS'] . $archivo;
	
		// Conexión SSH
		$connection = ssh2_connect($ftpServer, $port);
		if (!$connection) {
			die('No se pudo establecer la conexión SSH.');
		}
	
		// Autenticación SSH
		if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
			die('No se pudo autenticar en el servidor SSH.');
		}
	
		// Inicialización de SFTP
		$sftp = ssh2_sftp($connection);
		if (!$sftp) {
			die('No se pudo inicializar el subsistema SFTP.');
		}
	
	
		// Crear la ruta del archivo en el sistema SFTP
		$remoteFilePath = "ssh2.sftp://" . intval($sftp) . '/' . ltrim($remoteFile, '/');
		error_log("Ruta remota: $remoteFilePath");
	
		// Verificar la existencia del archivo
		
		$stat = ssh2_sftp_stat($sftp, $remoteFile);
		if ($stat === false) {
			Yii::app()->user->setFlash('error', 'No hay recaudos disponibles para este aportante.');
	
			// Redirigir a la vista 'index'
			$this->redirect(array('index'));
		}
	
		if ($stat['size'] === 0) {
			Yii::app()->user->setFlash('error', 'No hay recaudos disponibles para este aportante.');
	
			// Redirigir a la vista 'index'
			$this->redirect(array('index'));
		}
	
		// Abrir el archivo remoto en modo binario
		$remoteFileStream = fopen($remoteFilePath, 'rb');
		if (!$remoteFileStream) {
			Yii::app()->user->setFlash('error', 'No hay recaudos disponibles para este aportante.');
	
			// Redirigir a la vista 'index'
			$this->redirect(array('index'));
		}
		
	
		// Leer el contenido del archivo
		$fileContent = '';
		while (!feof($remoteFileStream)) {
			$buffer = fread($remoteFileStream, 8192); // Leer en bloques de 8KB
			if ($buffer === false) {
				Yii::app()->user->setFlash('error', 'No hay recaudos disponibles para este aportante.');
	
			// Redirigir a la vista 'index'
			$this->redirect(array('index'));
			}
			$fileContent .= $buffer; // Concatenar el contenido
		}
		fclose($remoteFileStream);
		
	
		// Verificar el tamaño del contenido
		if (strlen($fileContent) === 0) {
			//die('El archivo está vacío después de la lectura.');
			//Yii::app()->user->setFlash('error', 'No hay recaudos disponibles para este aportante.');
	
			// Redirigir a la vista 'index'
			//$this->redirect(array('index'));
			return 0;
		
		}
		
		if (strlen($fileContent) !== 0) {
		// Enviar encabezados para mostrar el PDF en el navegador
		header('Content-Type: application/pdf');
		header('Content-Disposition: inline; filename="' . basename($archivo) . '"');
		header('Content-Length: ' . strlen($fileContent));
	
		// Mostrar el contenido
		echo $fileContent;
		}
	
		exit;
	}

	public function actionCheckFileExistence($filePath)
    {
        // Configuración del servidor SSH/SFTP desde parámetros de la aplicación
        $ftpServer   = Yii::app()->params['FTPSERVER'];
        $ftpUsername = Yii::app()->params['FTPUSERNAME'];
        $ftpPassword = Yii::app()->params['FTPPASSWORD'];
        $port        = Yii::app()->params['PORT'];

        // Ruta remota del archivo
        $remoteFilePath = Yii::app()->params['REMOTESIS'] . $filePath;

        // Verificar si la extensión SSH2 está instalada
        if (!function_exists("ssh2_connect")) {
            throw new CHttpException(500, "La extensión SSH2 no está instalada.");
        }

        // Conectar al servidor SSH
        $connection = ssh2_connect($ftpServer, $port);
        if (!$connection) {
            throw new CHttpException(500, 'No se pudo conectar al servidor SSH.');
        }

        // Autenticación SSH
        if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
            throw new CHttpException(500, 'Fallo en la autenticación SSH.');
        }

        // Inicializar subsistema SFTP
        $sftp = ssh2_sftp($connection);
        if (!$sftp) {
            throw new CHttpException(500, 'No se pudo inicializar el subsistema SFTP.');
        }

        // Verificar si el archivo existe usando ssh2_sftp_stat
        $fileStat = @ssh2_sftp_stat($sftp, $remoteFilePath);
        if ($fileStat !== false) {
            return 1;
        } else {
            return 0;
        }

        // Cerrar la conexión SSH (opcional)
        ssh2_disconnect($connection);
    }

function obtenerUrlImagen($remote_path) {
    // Configuración de conexión
    $ftpServer = Yii::app()->params['FTPSERVER'];
    $ftpUsername = Yii::app()->params['FTPUSERNAME'];
    $ftpPassword = Yii::app()->params['FTPPASSWORD'];
    $port = Yii::app()->params['PORT'];
	
	// Conectar al servidor remoto usando SSH2
    $connection = ssh2_connect($ftpServer, $port);
    if (!$connection) {
        die("No se pudo conectar al servidor remoto.");
    }

    // Autenticación con el servidor remoto
    if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
        die("No se pudo autenticar en el servidor remoto.");
    }

    // Iniciar una sesión SFTP
    $sftp = ssh2_sftp($connection);
    if (!$sftp) {
        die("No se pudo iniciar la sesión SFTP.");
    }

    // Ruta remota de la imagen
	$imagen=Yii::app()->params['REMOTESIS'].$remote_path;
	//print_r($imagen);die();
    $remote_image_path = "ssh2.sftp://$sftp$imagen";

	//print_r($remote_image_path);die();

    // Verificar si la imagen existe en el servidor remoto
    if (file_exists($remote_image_path)) {
        // Generar la URL para acceder a la imagen
		$remote_server=Yii::app()->params['FTPURL'];
        $remote_url=$remote_server.$remote_path;
        return $remote_url;
    } else {
        return "La imagen no existe en el servidor remoto.";
    }
}

    public function VerImagen($remote_path)
    {
        // Configura las credenciales SSH y los detalles de conexión
        $ftpServer = Yii::app()->params['FTPSERVER'];
        $ftpUsername = Yii::app()->params['FTPUSERNAME'];
        $ftpPassword = Yii::app()->params['FTPPASSWORD'];
        $port = Yii::app()->params['PORT'];

        // Ruta del archivo en el servidor remoto
        $remoteFilePath = Yii::app()->params['REMOTESIS'] . $remote_path;
		//$remoteFilePath = $remote_path;

		//print_r($remoteFilePath);die();
		//Yii::app()->params['REMOTESIS'].

        // Conectar vía SSH2
        if (!function_exists("ssh2_connect")) {
            die("La extensión SSH2 no está instalada.");
        }

        $connection = ssh2_connect($ftpServer, $port);
        if (!$connection) {
            die('No se pudo conectar al servidor SSH.');
        }

        // Autenticarse
        if (!ssh2_auth_password($connection, $ftpUsername, $ftpPassword)) {
            die('Fallo en la autenticación SSH.');
        }

        // Crear un recurso SFTP
        $sftp = ssh2_sftp($connection);
        if (!$sftp) {
            die('No se pudo inicializar el subsistema SFTP.');
        }

        // Abrir el archivo remoto
        $remoteFileStream = @fopen("ssh2.sftp://$sftp$remoteFilePath", 'rb');
        if (!$remoteFileStream) {
            die('No se pudo abrir el archivo remoto.');
        }

        // Establecer el tipo MIME adecuado para la imagen
        header('Content-Type: image/jpeg');

        // Leer y enviar el archivo al navegador
        fpassthru($remoteFileStream);

        // Cerrar el archivo y la conexión SSH
        fclose($remoteFileStream);
        ssh2_disconnect($connection);
    }






	///LM

	function detallesMultaMaterialReporte($array_declaraciones_multa, $consultar) {
		$devolver = [];
	
		for ($i = 0; $i < count($array_declaraciones_multa); $i++) {
			$multa_material = SidcaiDeclaracionMulta::model()->find([
				'select' => 'decl_mult_monto, decl_mult_fecha',
				'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada AND mult_codigo_fk = :mult_codigo_fk',
				'params' => [
					':decl_codigo_fk' => $array_declaraciones_multa[$i],
					':mult_habilitada' => TRUE,
					':mult_codigo_fk' => 1
				],
				'order' => 'decl_mult_codigo_pk DESC'
			]);
	
			if ($multa_material != null) {
				if ($consultar) {
					$monto = self::reconversion($multa_material->decl_mult_fecha, $multa_material->decl_mult_monto);
				} else {
					$monto = bcdiv(self::reconversion($multa_material->decl_mult_fecha, $multa_material->decl_mult_monto), '1', 2);
				}
	
				// Convertir el monto a una cadena en formato decimal
				$monto = number_format($monto, 6, '.', '');
	
				$devolver[$array_declaraciones_multa[$i]] = bcdiv($monto, '1', 2);
			}
		}
	
		return $devolver;
	}

	function detallesInteresesMoratoriosReporte($array_declaraciones_multa, $consultar) {
		$devolver = [];
	
		for ($i = 0; $i < count($array_declaraciones_multa); $i++) {
			$intereses = SidcaiMultaInteres::model()->find([
				'select' => 'mult_monto, fecha_registro, mult_habilitada',
				'condition' => 'decl_codigo_fk = :decl_codigo_fk AND mult_habilitada = :mult_habilitada',
				'params' => [
					':decl_codigo_fk' => $array_declaraciones_multa[$i],
					':mult_habilitada' => TRUE,
				],
				'order' => 'mult_codigo_pk DESC'
			]);
	
			if ($intereses != null) {
				if ($consultar) {
					if ($intereses->mult_habilitada == true)
						$monto = self::reconversion($intereses->fecha_registro, $intereses->mult_monto);
					else
						continue;
				} else {
					$monto = bcdiv(self::reconversion(false, $intereses->mult_monto), '1', 2);
				}
	
				// Convertir el monto a una cadena en formato decimal
				$monto = number_format($monto, 6, '.', '');
	
				$devolver[$array_declaraciones_multa[$i]] = bcdiv($monto, '1', 2);
			}
		}
	
		return $devolver;
	}
	

	
}

?>
