<?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;  
		    //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'] : '';
	}


	/**
	 * 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);
		
        
		$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{
		$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;
	}


	/**
	 * 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'];
		/* var_dump($array_string);
		exit; */
		$mensual = false;
		foreach($declaraciones['declaraciones'] as $declaracion) {
			if($declaracion->decl_tipodeclaracion == 'M') {
				$mensual = true;
			}
		}
		$monto_aportado = 0.00;
		/* 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>"; */
						if(!empty($credito) && $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){
						$credito = $credito[0] + $aporte;
					}else{
						$credito = $credito[0];
					}
					/* 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 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){
			/* var_dump('llega');exit; */
			// Obtener el año actual 
			/* $year_actual = date('Y');
			$year_nuevo = $year_actual - 1; */
			/* var_dump($year_nuevo);exit; */

			//$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"));
			/* var_dump($inicio_periodo_fiscal_anterior);
			var_dump($final_periodo_fiscal_anterior);exit; */

			$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"],
						/* ':estatus' => 1003, */
						':decl_fechainicio_base' => $inicio_periodo_fiscal_anterior,
						':decl_fechafin_base' => $final_periodo_fiscal_anterior
					),
					'limit' => 1
				)
			);
			/* var_dump($aportante["apor_codigo_pk"]);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
					)
				);
				/* 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){
					/* var_dump('true');exit; */
					$objeto_aportante['aportante'] = TRUE;
					$objeto_aportante['periodo'] = date("Y-m-d", strtotime($inicio_periodo_fiscal_anterior." + 1 year"));
					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;
		}
		/* 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,
					),
				)
			);
			/* 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));
				}
				/* var_dump($year_periodo_actual);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($final_periodo_actual);exit; */

				if (date('Y-m-d') >= strtotime($final_periodo_actual)) {
					$year_tope = date('Y', strtotime($final_periodo_actual));
				}else{
					/* 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) {
						/* 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"));
					}
				}
				/* var_dump($year_verificar);
				var_dump($year_tope);
				exit; */

				for ($year_verificar ; $year_verificar <= $year_tope ; $year_verificar++) { 
					$fecha = $year_verificar . date("-m-d", strtotime($fecha_inicio));
					$conciliacion = SidcaiCasillasIslr::model()->find(
						array(
							'condition' => 'apor_codigo_fk = :apor_codigo AND periodo_fiscal = :periodo_fiscal ',
							'params' => array(
								':apor_codigo' => $aportante->apor_codigo_pk,
								':periodo_fiscal' => $fecha,
							),
						)
					);
					/* var_dump($conciliacion);exit; */
					/* var_dump($year_verificar);exit; */
					//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 . '%', 
							),
						)
					);
					
					if ($verificar_anual == Null) {
						/* 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){
							$array_aportante['conciliacion'] = TRUE;
							$array_aportante['periodo'] = $fecha;
							$array_aportante['data'] = $conciliacion != NULL ? $conciliacion : NULL;
							return $array_aportante;
							break;
						}
					}
				}

				$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'],
			]
		]);

		$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_requerido);exit; */
		$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(false,$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(false,$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(false,$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;

        // 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'
		]);
		


        if($declaracion != null){
        	if($declaracion->esta_codigo_fk == 1003 || $declaracion->esta_codigo_fk == 1004){
	        	// 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, $filename) {
		$path = Yii::getAlias($directory);
		$file = $path . '/' . $filename;
	
		if (is_dir($path)) {
			echo "La carpeta '$directory' existe.\n";
		} else {
			echo "La carpeta '$directory' no existe.\n";
		}
	
		if (file_exists($file)) {
			echo "El archivo '$filename' existe en la carpeta '$directory'.\n";
		} else {
			echo "El archivo '$filename' no existe en la carpeta '$directory'.\n";
		}
	}
	
	// Ejemplo de uso
	//checkPathAndFile('@app/path/to/your/directory', 'yourfile.txt');


	public function directoryExists($remoteDir)
    {
        // Conectar al servidor FTP
        $ftpConn = ftp_connect($this->ftpServer);
        if ($ftpConn && ftp_login($ftpConn, $this->ftpUsername, $this->ftpPassword)) {
            // Intentar cambiar al directorio remoto
            if (ftp_chdir($ftpConn, $remoteDir)) {
                ftp_close($ftpConn);
                return true;
            } else {
                ftp_close($ftpConn);
                return false;
            }
        } else {
            throw new \Exception("Fallo en la conexión FTP o autenticación.");
        }
    }

	//EJEMPLO DE USO

	/*
	$ftpServer = Yii::app()->params['FTPSERVER'];
	$ftpUsername = Yii::app()->params['FTPUSERNAME'];
	$ftpPassword = Yii::app()->params['FTPPASSWORD'];
	$remoteDir = Yii::app()->params['REMOTEDIR'];


	try {
		$checker = new RemoteDirectoryChecker($ftpServer, $ftpUsername, $ftpPassword);
		if ($checker->directoryExists($remoteDir)) {
			echo "La carpeta existe en el servidor remoto.";
		} else {
			echo "La carpeta no existe en el servidor remoto.";
		}
	} catch (\Exception $e) {
		echo "Error: " . $e->getMessage();
	}
	*/
	

	//end LM


}

?>
