<?php

/**
 * caco_liq_carte_contr actions.
 *
 * @package    cartera
 * @subpackage caco_liq_carte_contr
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class caco_liq_carte_contrActions extends sfActions {

    /**
     * Liquidacion de contratos cartera
     *
     * @param sfRequest $request A request object
     */
    public function executeList(sfWebRequest $request) {

        //Revisar que sea post
        //$this->forward404Unless($request->isMethod('post'));
        //Guardar los parametros del request en el log
        $this->logMessage("---BEGIN Logging request");
        foreach ($request->getPostParameters() as $key => $value) {
            $this->logMessage("request[$key] = $value");
        }
        $this->logMessage("--------------------------------------------------* Ip: " . $_SERVER['REMOTE_ADDR']);
        foreach ($request->getGetParameters() as $key => $value) {
            $this->logMessage("request[$key] = $value");
        }
        $this->logMessage("---END Logging request");

        /*
         * Se instancia la clase del manejo del log
         */
        $logger = sfContext::getInstance()->getLogger();

        $records = array();

        /**
         * Abrir nueva conexion con la Base de Datos
         */
        $this->conn = Doctrine_Manager::getInstance()->getCurrentConnection();
        $this->conn->beginTransaction();

        /*
         * Formato de fecha
         */
        //Sql
        $sql = <<<EOD
ALTER SESSION SET NLS_DATE_FORMAT = "YYYY-MM-DD" 
EOD;
        //Ejecutar SQL
        CN_TABLE::executeSQL($sql);

        try {

            /*
             * Variables de filtro
             */
            //Periodo
            $id_anhos = $request['id_anhos'];
            $id_meses = $request['id_meses'];

            $progress_key = $request['progress_key'] . $request['username'];
            $username = $request['username'];
            MemcacheHandler::getInstance()->set($progress_key, 0);

            $logPath = sfConfig::get('sf_log_dir') . '/liquidacion.log';
            $custom_logger = new sfFileLogger(new sfEventDispatcher(), array('file' => $logPath));

            //Iniciar variables
            $id_liq_novedad_contrato = "";

            //id_contrato
            $id_contrato = null;
            $whereContrato = "";
            if (isset($request['id_contrato'])) {
                $id_contrato = $request['id_contrato'];
                $whereContrato = " AND tab0.id_contrato = " . $request['id_contrato'];
            }

            /*
             *  Borrar datos anteriores Periodo-contrato
             */
            //Sql
            $sql = <<<EOD
delete from CACO_LIQ_CALCULO_INT_BANCO tab0
where
tab0.id_liq_novedad_contrato in
(
    select tab0.id_liq_novedad_contrato from caco_liq_novedad_contrato tab0
    where
    tab0.id_anhos = $id_anhos
    and tab0.id_meses = $id_meses
    $whereContrato
)                      
EOD;
            //Ejecutar SQL
            $this->conn->execute($sql);

            //Sql
            $sql = <<<EOD
delete from CACO_LIQ_CALCULO_INT_MORA tab0
where
tab0.id_liq_novedad_contrato in
(
    select tab0.id_liq_novedad_contrato from caco_liq_novedad_contrato tab0
    where
    tab0.id_anhos = $id_anhos
    and tab0.id_meses = $id_meses
    $whereContrato
)                      
EOD;
            //Ejecutar SQL
            $this->conn->execute($sql);

            //Sql
            $sql = <<<EOD
delete from CACO_LIQ_CALCULO_INDEXACION tab0
where
tab0.id_liq_novedad_contrato in
(
    select tab0.id_liq_novedad_contrato from caco_liq_novedad_contrato tab0
    where
    tab0.id_anhos = $id_anhos
    and tab0.id_meses = $id_meses
    $whereContrato
)                    
EOD;
            //Ejecutar SQL
            $this->conn->execute($sql);

            //Sql 
            $sql = <<<EOD
delete from CACO_LIQ_NOVEDAD_CONTRATO tab0
where
tab0.id_anhos = $id_anhos
and tab0.id_meses = $id_meses  
$whereContrato                     
EOD;
            //Ejecutar SQL
            $this->conn->execute($sql);

            /*
             * COMMIT DE TODAS LAS TRANSACCIONES
             */
            $this->conn->commit();

            /**
             * Abrir nueva conexion con la Base de Datos
             */
            $this->conn = Doctrine_Manager::getInstance()->getCurrentConnection();
            $this->conn->beginTransaction();

            /**
             * LIQUIDACION
             */
            /*
             * Recorrer contratos segun novedad
             * 1ro. Se filtra la base por el “Estado”:
              • Acta legalizada
              • Acta Unilateral
              2do. Se filtra quitando los contratos que tienen salvedades
              3ro. Se filtra por los que tengan “SALDO A REINTEGRAR”
              4to. Se filtra por los que no presenten reintegro
              5to. Como fecha de reintegro se coloca la fecha a la cual se requiere el valor de cálculo de interés moratorio
             */
            //Sql
            $sql = <<<EOD
select distinct
tab0.*
from(

    SELECT
    tab0.*,
                    
    nov.ID_NOVEDAD_CONTRATO,
    nov.ID_TS_TD,
    nov.DOC_SOPORTE,
    nov.ID_TIPO_NOV_CONT,
    nov.FECHA_NOVEDAD,
    nov.OBSERVACIONES,
    nov.VALOR_DESEMBOLSADO,
    nov.VALOR_RENDIMIENTOS,
    nov.VALOR_NO_EJECUTADO,
    nov.VALOR_NO_RECONOCIDO,
    nov.INDEXACION,
    nov.VALOR_INTERESES_MORA,
    nov.VALOR_INTERESES_BANCO,
    nov.REINTEGROS_EFECTUADOS,
    nov.NO_CERTIFICADO,
    nov.DESTINATARIO,
    nov.DESTINATARIO_CARGO,
    nov.NO_RADICADO,
    nov.OBJETO,
    nov.FECHA_LEGALIZACION,
    nov.DIAS_LEG,
    nov.fecha_legalizacion + nov.dias_leg as fecha_legalizacion_real, 
    nov.OBSER_INDEXACION,
    nov.OBSER_INTERES_MORA,
    nov.OBSER_INTERES_BANCO,
    nov.OBSER_SALDO_PENDIENTE,
    nov.ANEXO_CETIFICADO,
    nov.FIRMADO,
    nov.FECHA_FIRMADO,
    nov.USUARIO_FIRMADO,
    nov.VALOR_AJUSTE_BANCO,
    nov.VALOR_AJUSTE_MORA,
    nov.FECHA_LEGALIZACION_LIMITE,
    nov.VALOR_AJUSTE_INDEXACION,
    nov.APLICA_DIA_ANT,
    
    calind.fecha_inicial_indexacion,
    calind.fecha_final_indexacion,
    
    last_day(to_date( $id_anhos ||'-'|| $id_meses ||'-01','yyyy-mm-dd')) as fecha_proceso_legal,    
    
    nvl( nov.valor_no_ejecutado ,0) as no_ejecutados,
    nvl( nov.valor_no_reconocido ,0) as no_reconocidos,
    nvl( nov.valor_no_ejecutado + nov.valor_no_reconocido ,0) as vlr_reintegrar,
    nvl( nov.indexacion ,0) + nvl( nov.valor_ajuste_indexacion ,0) as vlr_indexacion,
    nvl( nov.valor_intereses_mora ,0) + nvl( nov.valor_ajuste_mora ,0) as vlr_interes_moratorio,
    nvl( nov.valor_intereses_banco ,0) + nvl( nov.valor_ajuste_banco ,0) as vlr_interes_bancario,
    nvl( nov.valor_no_ejecutado + nov.valor_no_reconocido + nov.indexacion + nov.valor_intereses_mora + nov.valor_intereses_banco + nov.valor_ajuste_indexacion + nov.valor_ajuste_mora + nov.valor_ajuste_banco ,0) as valor_total,

    tarein.fecha_novedad as fecha_reintegro,
    nvl( ta.no_ejecutados_rein ,0) as no_ejecutados_rein,
    nvl( ta1.no_aprobados_rein ,0) as no_aprobados_rein,
    nvl( ta2.intereses ,0) as vlr_interes_ib,
    nvl( ta3.intereses ,0) as vlr_interes_im,
    nvl( ta4.intereses ,0) as vlr_interes_ix,
    nvl( ta.no_ejecutados_rein ,0) + nvl( ta1.no_aprobados_rein ,0) + nvl( ta2.intereses ,0) + nvl( ta3.intereses ,0) + nvl( ta4.intereses ,0) as vlr_reintegrado,

    nvl( (nvl( nov.valor_no_ejecutado + nov.valor_no_reconocido + nov.indexacion + nov.valor_intereses_mora + nov.valor_intereses_banco + nov.valor_ajuste_indexacion + nov.valor_ajuste_mora + nov.valor_ajuste_banco ,0))
        - ( nvl( ta.no_ejecutados_rein ,0) + nvl( ta1.no_aprobados_rein ,0) + nvl( ta2.intereses ,0) + nvl( ta3.intereses ,0) + nvl( ta4.intereses ,0) )
    ,0) as saldo_pendiente,
    
    ( nvl( nov.valor_no_ejecutado ,0) + nvl( nov.valor_no_reconocido ,0) ) - ( nvl( ta.no_ejecutados_rein ,0) - nvl( ta1.no_aprobados_rein ,0) ) as saldo_capital 
    
    FROM caco_contrato tab0
    
    join(
    
        select
        tipnov.codigo as codigo_tipnov,
        tipnov.descripcion as descripcion_tipnov,
        novcon.*,
        ROW_NUMBER() OVER (
            partition by novcon.id_contrato
            ORDER BY novcon.id_contrato, novcon.fecha_novedad desc
        ) AS rn
    
        from caco_novedad_contrato_v novcon
    
        left join caco_tipo_nov_cont tipnov
        on tipnov.id_tipo_nov_cont = novcon.id_tipo_nov_cont
    
        where
        tipnov.aplica_cartera in (0,1)
        and extract(year from novcon.fecha_novedad) || lpad(extract(month from novcon.fecha_novedad), 2, '0')  <= $id_anhos || lpad($id_meses, 2, '0')
        and novcon.firmado = 1
    
    )nov
    on nov.id_contrato = tab0.id_contrato
    and nov.rn = 1

    left join (
        select tab22.id_contrato,
        sum(tab22.valor_reintegro)	 as no_ejecutados_rein
         from caco_novedad_reintegro tab22
        where tab22.tipo_valor = 'RE'
        and extract(year from tab22.fecha_novedad) || lpad(extract(month from tab22.fecha_novedad), 2, '0')  <= $id_anhos || lpad($id_meses, 2, '0')
        GROUP BY tab22.id_contrato,tab22.tipo_valor
    )ta ON ta.id_contrato=tab0.id_contrato

    left join (
        select tab21.id_contrato,
        sum(tab21.valor_reintegro)	 as no_aprobados_rein
         from caco_novedad_reintegro tab21
        where tab21.tipo_valor = 'RC'
        and extract(year from tab21.fecha_novedad) || lpad(extract(month from tab21.fecha_novedad), 2, '0')  <= $id_anhos || lpad($id_meses, 2, '0')
        GROUP BY tab21.id_contrato,tab21.tipo_valor
    )ta1 ON ta1.id_contrato=tab0.id_contrato

    left join (
        select tab20.id_contrato,
        sum(tab20.valor_reintegro)	 as intereses
         from caco_novedad_reintegro tab20
        where tab20.tipo_valor = 'IB' 
        and extract(year from tab20.fecha_novedad) || lpad(extract(month from tab20.fecha_novedad), 2, '0')  <= $id_anhos || lpad($id_meses, 2, '0')
        GROUP BY tab20.id_contrato,tab20.tipo_valor
    )ta2 ON ta2.id_contrato=tab0.id_contrato

    left join (
        select tab20.id_contrato,
        sum(tab20.valor_reintegro)	 as intereses
         from caco_novedad_reintegro tab20
        where tab20.tipo_valor = 'IM'
        and extract(year from tab20.fecha_novedad) || lpad(extract(month from tab20.fecha_novedad), 2, '0')  <= $id_anhos || lpad($id_meses, 2, '0')
        GROUP BY tab20.id_contrato,tab20.tipo_valor
    )ta3 ON ta3.id_contrato=tab0.id_contrato

    left join (
        select tab20.id_contrato,
        sum(tab20.valor_reintegro)	 as intereses
         from caco_novedad_reintegro tab20
        where tab20.tipo_valor = 'IX'
        and extract(year from tab20.fecha_novedad) || lpad(extract(month from tab20.fecha_novedad), 2, '0')  <= $id_anhos || lpad($id_meses, 2, '0')
        GROUP BY tab20.id_contrato,tab20.tipo_valor
    )ta4 ON ta4.id_contrato=tab0.id_contrato

    left join (
        select tarein.id_contrato,
        min(tarein.fecha_novedad)	 as fecha_novedad
         from caco_novedad_reintegro tarein
        GROUP BY tarein.id_contrato
    )tarein ON tarein.id_contrato=tab0.id_contrato
        
    left join (
        select
        aux.id_novedad_contrato,
        aux.id_contrato,
        min(aux.fecha_ini) as fecha_inicial_indexacion,
        max(aux.fecha_fin) as fecha_final_indexacion
        
        from caco_calculo_indexacion aux
        
        group by
        aux.id_novedad_contrato,
        aux.id_contrato    
    )calind
    on calind.id_novedad_contrato = nov.id_novedad_contrato
    and calind.id_contrato = nov.id_contrato    
    
    where
    0 != 1
    --and tab0.aplica_salvedad = 0
    $whereContrato 

)tab0

order by
tab0.id_anhos,
tab0.codigo,
tab0.id_tipo_contrato                        
EOD;
            //Ejecutar SQL
            $records = CN_TABLE::executeSQL($sql);
            $i = 1;
            $nom_id_contrato = count($records);

            // Antes de inicar el proceso largo
            $brecha = 1;
            if ($nom_id_contrato > 100)
                $brecha = $nom_id_contrato - (0.99 * $nom_id_contrato);

            $this->logMessage("[caco_liq_carte_contr] nom_id_contrato: " . $nom_id_contrato);

            foreach ($records as $value) {

                $id_liq_novedad_contrato = "";

                // Guardar un valor en el proceso largo
                if ($i % $brecha == 0) {
                    //validar que no sobrepase el 100 porciento - 20151007
                    if ((round(($i / $nom_id_contrato) * 100)) < 100) {
                        MemcacheHandler::getInstance()->set($progress_key, round(($i / $nom_id_contrato) * 100, 0));
                    }
                }

                $this->logMessage("[caco_liq_carte_contr] Existen contratos.");

                //Fecha de proceso al cual calcula la liquidacion
                $fecha_proceso_legal = $value['fecha_proceso_legal'];
                $fecha_legalizacion_real = $value['fecha_legalizacion_real'];
                $saldo_capital = $value['saldo_capital'];

                //Datos contrato
                $id_contrato = $value['id_contrato'];
                $codigo_cont = $value['codigo'];
                $id_anhos_cont = $value['id_anhos'];

                $custom_logger->info(MemcacheHandler::getInstance()->get($progress_key) . " - Procesado $i de $nom_id_contrato conceptos. Contrato id: " . $id_contrato . "");
                $custom_logger->info(MemcacheHandler::getInstance()->get($progress_key) . " - Contrato : " . $codigo_cont . "-" . $id_anhos_cont . "\n");

                //Datos Novedad
                $id_novedad_contrato = $value['id_novedad_contrato'];
                $id_ts_td = $value['id_ts_td'];
                $doc_soporte = $value['doc_soporte'];
                $id_tipo_nov_cont = $value['id_tipo_nov_cont'];
                $observaciones = $value['observaciones'];
                $valor_desembolsado = $value['valor_desembolsado'];
                $valor_rendimientos = $value['valor_rendimientos'];
                $valor_no_ejecutado = $value['valor_no_ejecutado'];
                $valor_no_reconocido = $value['valor_no_reconocido'];
                //Datos generales
                $indexacion = $value['indexacion'];
                $valor_intereses_mora = $value['valor_intereses_mora'];
                $valor_intereses_banco = $value['valor_intereses_banco'];
                $vlr_reintegrado = $value['vlr_reintegrado'];
                $no_certificado = $value['no_certificado'];
                $destinatario = $value['destinatario'];
                $destinatario_cargo = $value['destinatario_cargo'];
                $no_radicado = $value['no_radicado'];
                $objeto = $value['objeto'];
                $fecha_legalizacion = $value['fecha_legalizacion'];
                $dias_leg = $value['dias_leg'];
                $obser_indexacion = $value['obser_indexacion'];
                $obser_interes_mora = $value['obser_interes_mora'];
                $obser_interes_banco = $value['obser_interes_banco'];
                $obser_saldo_pendiente = $value['obser_saldo_pendiente'];
                $anexo_cetificado = $value['anexo_cetificado'];
                $firmado = $value['firmado'];
                $fecha_firmado = $value['fecha_firmado'];
                $usuario_firmado = $value['usuario_firmado'];
                $valor_ajuste_banco = $value['valor_ajuste_banco'];
                $valor_ajuste_mora = $value['valor_ajuste_mora'];
                $fecha_legalizacion_limite = $value['fecha_legalizacion_limite'];
                $valor_ajuste_indexacion = $value['valor_ajuste_indexacion'];
                $aplica_dia_ant = $value['aplica_dia_ant'];
                //Datos Reintegro
                $fecha_reintegro = $value['fecha_reintegro'];
                $no_ejecutados_rein = $value['no_ejecutados_rein'];
                $no_aprobados_rein = $value['no_aprobados_rein'];
                $vlr_interes_ib = $value['vlr_interes_ib'];
                $vlr_interes_im = $value['vlr_interes_im'];
                $vlr_interes_ix = $value['vlr_interes_ix'];
                $saldo_pendiente = $value['saldo_pendiente'];
                //Datos Indexacion
                $fecha_inicial_indexacion = $value['fecha_inicial_indexacion'];
                $fecha_final_indexacion = $value['fecha_final_indexacion'];

                /**
                 * Validar saldo pendiente
                 */
                //if ($saldo_capital <= 0) {
                if (true) {//PARA ACTUALIZAR BASE, luego dejar como estaba 20230704
                    //Si no tiene saldo genera copia del registro antiguo-ultima novedad
                    $this->logMessage("[caco_liq_carte_contr] Si no tiene saldo genera copia del registro antiguo-ultima novedad.");

                    //Crea copia liq
                    $sql = <<<EOD
insert into caco_liq_novedad_contrato (id_liq_novedad_contrato,id_anhos,id_meses,id_contrato,id_ts_td,doc_soporte,id_tipo_nov_cont,
    fecha_novedad,observaciones,fecha_log,usuario_log,valor_desembolsado,valor_rendimientos,valor_no_ejecutado,valor_no_reconocido,    
        indexacion,valor_intereses_mora,valor_intereses_banco,reintegros_efectuados,no_certificado,destinatario,destinatario_cargo,
            no_radicado,objeto,fecha_legalizacion,dias_leg,obser_indexacion,obser_interes_mora,obser_interes_banco,obser_saldo_pendiente,
                anexo_cetificado,firmado,fecha_firmado,usuario_firmado,valor_ajuste_banco,valor_ajuste_mora,fecha_legalizacion_limite,valor_ajuste_indexacion,aplica_dia_ant,
            fecha_reintegro,no_ejecutados_rein,no_aprobados_rein,vlr_interes_ib,vlr_interes_im,vlr_interes_ix,saldo_pendiente)  
values (null,'$id_anhos','$id_meses','$id_contrato','$id_ts_td','$doc_soporte','$id_tipo_nov_cont',
    last_day(to_date( $id_anhos ||'-'|| $id_meses ||'-01','yyyy-mm-dd')),'$observaciones',trunc(sysdate),'$username','$valor_desembolsado','$valor_rendimientos','$valor_no_ejecutado','$valor_no_reconocido',
        '$indexacion','$valor_intereses_mora','$valor_intereses_banco','$vlr_reintegrado','$no_certificado','$destinatario','$destinatario_cargo',
            '$no_radicado','$objeto',to_date( '$fecha_legalizacion','yyyy-mm-dd'),'$dias_leg','$obser_indexacion','$obser_interes_mora','$obser_interes_banco','$obser_saldo_pendiente',
                '$anexo_cetificado','$firmado',to_date('$fecha_firmado','yyyy-mm-dd'),'$usuario_firmado','$valor_ajuste_banco','$valor_ajuste_mora',to_date('$fecha_legalizacion_limite','yyyy-mm-dd'),'$valor_ajuste_indexacion','$aplica_dia_ant',
            to_date( '$fecha_reintegro','yyyy-mm-dd'),'$no_ejecutados_rein','$no_aprobados_rein','$vlr_interes_ib','$vlr_interes_im','$vlr_interes_ix','$saldo_pendiente') 
EOD;
                    $this->conn->execute($sql);

                    //Consultar liq creada
                    $sql = <<<EOD
SELECT
    *
FROM caco_liq_novedad_contrato
where id_contrato = $id_contrato
and id_anhos = $id_anhos
and id_meses = $id_meses   
EOD;
                    //Ejecutar SQL
                    $records_liq = CN_TABLE::executeSQL($sql);
                    $id_liq_novedad_contrato = $records_liq[0]['id_liq_novedad_contrato'];

                    //crea copia de intereses IB
                    $sql = <<<EOD
insert into CACO_LIQ_CALCULO_INT_BANCO (ID_LIQ_NOVEDAD_CONTRATO,ID_CONTRATO,VIGENCIA_MES,FECHA_INI,FECHA_FIN,
    ID_ANHOS,ID_MESES,DIAS,TASA_ANU,TASA_MEN,VALOR_CAPITAL,VALOR_INTERES)

SELECT
$id_liq_novedad_contrato as ID_LIQ_NOVEDAD_CONTRATO,
ID_CONTRATO,
VIGENCIA_MES,
FECHA_INI,
FECHA_FIN,
ID_ANHOS,
ID_MESES,
DIAS,
TASA_ANU,
TASA_MEN,
VALOR_CAPITAL,
VALOR_INTERES

FROM caco_calculo_interes_banco

where 
id_novedad_contrato = $id_novedad_contrato
and id_contrato = $id_contrato 

order by
fecha_ini,
fecha_fin
EOD;
                    $this->conn->execute($sql);

                    //crea copia de intereses IM
                    $sql = <<<EOD
insert into CACO_LIQ_CALCULO_INT_MORA (ID_LIQ_NOVEDAD_CONTRATO,ID_CONTRATO,FECHA_INI,FECHA_FIN,
    DIAS,TASA_INTERES_BANC,VALOR_CAPITAL,VALOR_INTERES)

SELECT
$id_liq_novedad_contrato as ID_LIQ_NOVEDAD_CONTRATO,
ID_CONTRATO,
FECHA_INI,
FECHA_FIN,
DIAS,
TASA_INTERES_BANC,
VALOR_CAPITAL,
VALOR_INTERES

FROM caco_calculo_interes_mora

where 
id_novedad_contrato = $id_novedad_contrato
and id_contrato = $id_contrato 

order by
fecha_ini,
fecha_fin 
EOD;
                    $this->conn->execute($sql);

                    //crea copia de intereses IX
                    $sql = <<<EOD
insert into CACO_LIQ_CALCULO_INDEXACION (ID_LIQ_NOVEDAD_CONTRATO,ID_CONTRATO,FECHA_INI,FECHA_FIN,
    TASA_TOTAL_IND,VALOR_CAPITAL,VALOR_IND,IPC_INCIAL,IPC_FINAL)

SELECT
$id_liq_novedad_contrato as ID_LIQ_NOVEDAD_CONTRATO,
ID_CONTRATO,
FECHA_INI,
FECHA_FIN,
TASA_TOTAL_IND,
VALOR_CAPITAL,
VALOR_IND,
IPC_INCIAL,
IPC_FINAL

FROM caco_calculo_indexacion

where 
id_novedad_contrato = $id_novedad_contrato
and id_contrato = $id_contrato 

order by
fecha_ini,
fecha_fin
EOD;
                    $this->conn->execute($sql);
                } else {
                    //Crear liquidacion para los contratos que apliquen
                    $this->logMessage("[caco_liq_carte_contr] Crear liquidacion para los contratos que apliquen.");

                    //Calculos intereses
                    $indexacion = 0;
                    $valor_intereses_mora = 0;
                    $valor_intereses_banco = 0;

                    //Verifica consecutivo maximo
                    $sql = <<<EOD
select * from caco_tipo_nov_cont 
    where id_tipo_nov_cont = $id_tipo_nov_cont
EOD;
                    $records = CN_TABLE::executeSQL($sql);

                    if (count($records) > 0) {
                        $aplica_cartera = $records[0]['aplica_cartera'];

                        //Se obliga a calcular int bancario pendiente completar con la novedad normal - 20210819
                        $tag_aplica_inter_banc = false;
                        $reg_no_aplica_cartera = 0;

                        if ($aplica_cartera == 1 && $fecha_legalizacion != null && $reg_no_aplica_cartera == 0) {
                            $logger->info("Calculo de intereses tag_aplica_inter_banc");
                            $tag_aplica_inter_banc = true;
                        }

                        /**
                         * Calculo de intereses Bancarios - 20190313
                         * $tag_aplica_inter_banc, Si aplica para calculo banc al registrar los moratorios(tipo acta legalizacion) - 20190426
                         */
                        if ($aplica_cartera == 0 || $tag_aplica_inter_banc) {
                            $logger->info("INICIO Calculo de intereses Bancarios");

                            /*
                             * Verifica valores de calculo
                             * Pendiente fecha reintegro primero
                             * Si aplica calculo de intereses banco - 20190404
                             * Se toma el reintegro de la ultima novedad firmada y con relacion activa(novdeb.estado = 1) - 20190415
                             */
                            $sql = <<<EOD
select 
extract(month from tab1.fecha_caculo_int_banc) || extract(year from tab1.fecha_caculo_int_banc)  as mes_ini_int_banc,   
to_char(tab1.fecha_caculo_int_banc,'yyyy-mm-dd') as fecha_caculo_int_banc,
to_char(cred.fecha_novedad,'yyyy-mm-dd') as fecha_reintegro,
nvl(cred.valor_reintegro,0) as valor_reintegro 
                            
from caco_contrato tab1

left join(

    select
    id_contrato,
    min(fecha_novedad) as fecha_novedad,
    sum(valor_reintegro) as valor_reintegro,
    sum(valor_excedente) as valor_excedente
    
    FROM caco_novedad_reintegro
    
    where
    id_contrato = $id_contrato 
    and tipo_valor in ( 'RE' )
    and extract(year from fecha_novedad) || lpad(extract(month from fecha_novedad), 2, '0')  <= $id_anhos || lpad($id_meses, 2, '0')    
                                    
    group by
    id_contrato

)cred
on cred.id_contrato = tab1.id_contrato
                            
where tab1.id_contrato = $id_contrato 
and tab1.aplica_interes_banco = 1 
EOD;
                            $records = CN_TABLE::executeSQL($sql);
                            if (count($records) > 0) {

                                $valor_reintegro = $records[0]['valor_reintegro'];

                                $mes_ini_int_banc = $records[0]['mes_ini_int_banc'];
                                $fecha_ini = $records[0]['fecha_caculo_int_banc'];
                                $fecha_fin = $fecha_proceso_legal;
                                $valor_capital = $valor_no_ejecutado;
                                $tag_ini = 0;
                                $tag_fin = 0;

                                /**
                                 * Validaciones de fecha reintegro, legalizacion y actual - 20190319
                                 */
                                if ($fecha_legalizacion != null) {
                                    $logger->info("Entro a Validaciones de fecha reintegro, legalizacion y actual");
                                    $datetime1 = new DateTime($fecha_legalizacion);
                                    $datetime2 = new DateTime($fecha_fin);
                                    if ($datetime1 < $datetime2) {
                                        $fecha_fin = $fecha_legalizacion;
                                        $tag_fin = 1;
                                    }
                                }

                                if ($tag_fin == 1) {
                                    /**
                                     * Restar dia si no es la actual - 20190319
                                     * to_char(to_date('$fecha_fin', 'yyyy-mm-dd')-1, 'yyyy-mm-dd') as fecha_fin
                                     * Se cambia hasta el dia de leg., no se pierda dias - 20200930
                                     * Se resta dias si aplica_dia_ant - 20201126
                                     */
                                    $dia_ant = 0;
                                    if ($aplica_dia_ant == '1') {
                                        $dia_ant = 1;
                                    }

                                    $logger->info("Entro a Restar dia si no es la actual");
                                    $sql = <<<EOD
select 
to_char(to_date('$fecha_fin', 'yyyy-mm-dd')-$dia_ant, 'yyyy-mm-dd') as fecha_fin
from dual 
EOD;

                                    //ejecuta y obtiene el resultado del sql
                                    $records = CN_TABLE::executeSQL($sql, true);
                                    $fecha_fin = $records[0]['fecha_fin'];
                                }

                                /*
                                 * Calculo mensual para meses de 30 - 20210301
                                 * 0-Cuando NO se marque el campo el sistema deberá liquidar los intereses con la fecha de legalización registrada.
                                 * 1-Cuando se marque el campo el sistema deberá liquidar los intereses un día antes de la fecha de legalización registrada.
                                 * 2-Calcula el mes de 30 dias, calculo mensual.
                                 */
                                $datetime1 = new DateTime($fecha_ini);
                                $datetime2 = new DateTime($fecha_fin);

                                ///Validar fecha ini y fin
                                if ($datetime1 < $datetime2) {
                                    $logger->info("Llamado a calculoInteresBancario");

                                    /**
                                     * Reintegro por novedad - 20200311
                                     */
                                    $sql = <<<EOD
SELECT
to_char(fecha_novedad,'yyyy-mm-dd') as fecha_novedad,
to_char(fecha_novedad-1,'yyyy-mm-dd') as fecha_novedad_ant,
valor_reintegro,
valor_excedente    
FROM caco_novedad_reintegro
where
id_contrato = $id_contrato 
and tipo_valor = 'RE'
order by
fecha_novedad,
id_novedad_reintegro 
EOD;
                                    $records = CN_TABLE::executeSQL($sql);
                                    if (count($records) > 0) {
                                        $logger->info("Con reintegro por novedad");

                                        $fecha_ini_nov = $fecha_ini;
                                        $fecha_fin_nov = $fecha_fin;
                                        $valor_capital_nov = $valor_capital;

                                        //Recorre cada novedad y hace llamado por cada rango de fecha segun novedad reintegro - 20200311
                                        foreach ($records as $value) {

                                            $fecha_novedad = $value['fecha_novedad'];
                                            $fecha_novedad_ant = $value['fecha_novedad_ant'];
                                            $valor_reintegro = $value['valor_reintegro'] - $value['valor_excedente'];

                                            $datetime1 = new DateTime($fecha_novedad);
                                            $datetime2 = new DateTime($fecha_fin);
                                            //Validar fecha ini y fin
                                            if ($datetime1 < $datetime2) {
                                                $fecha_fin_nov = $fecha_novedad_ant;
                                            }

                                            $logger->info("Llamar calculoInteresBancario fecha::" . $fecha_novedad);
                                            $logger->info("Llamar calculoInteresBancario valor::" . $valor_reintegro);
                                            $logger->info("Llamar calculoInteresBancario valor capital::" . $valor_capital_nov);

                                            $datetime1nov = new DateTime($fecha_ini_nov);
                                            $datetime2nov = new DateTime($fecha_fin_nov);
                                            //Validar saldo mayor que 0 y las fechas aplican
                                            if ($valor_capital_nov > 0 && $datetime1nov <= $datetime2nov) {

                                                $logger->info($datetime1nov->format('nY') . "::Verificar fecha ini y primer reintegro::" . $mes_ini_int_banc);
                                                if ($datetime1nov->format('nY') != "$mes_ini_int_banc") {
                                                    //$tag_ini = 1;//Se omite para que siempre el primer mes sea dias completos del mes - 20210907::LAVILA
                                                }

                                                $valor_interes_banco += $this->calculoInteresBancario($fecha_ini_nov, $fecha_fin_nov, $valor_capital_nov, $tag_ini, 1, $id_liq_novedad_contrato, $id_contrato, 0);
                                            }

                                            //nuevo valor a capital
                                            $valor_capital_nov = $valor_capital_nov - $valor_reintegro;
                                            //Validar que el reintegro es antes a la fecha inicial del contrato - 20210908::LAVILA                                    
                                            $datetime1novval = new DateTime($fecha_ini);
                                            $datetime2novval = new DateTime($fecha_novedad);
                                            if ($datetime1novval <= $datetime2novval) {
                                                $fecha_ini_nov = $fecha_novedad;
                                            }
                                        }

                                        $logger->info("Llamar calculoInteresBancario fecha_ini::" . $fecha_ini_nov);
                                        $logger->info("Llamar calculoInteresBancario fecha_fin::" . $fecha_fin);
                                        $logger->info("Llamar calculoInteresBancario valor capital::" . $valor_capital_nov);

                                        //Validar saldo mayor que 0
                                        if ($valor_capital_nov > 0) {

                                            $datetime1novmes = new DateTime($fecha_ini_nov);
                                            $logger->info($datetime1novmes->format('nY') . "::Verificar fecha ini y primer reintegro, para ulitmo llamado::" . $mes_ini_int_banc);
                                            if ($datetime1novmes->format('nY') != "$mes_ini_int_banc") {
                                                //$tag_ini = 1;//Se omite para que siempre el primer mes sea dias completos del mes - 20210907::LAVILA
                                            }

                                            $valor_interes_banco += $this->calculoInteresBancario($fecha_ini_nov, $fecha_fin, $valor_capital_nov, $tag_ini, $tag_fin, $id_liq_novedad_contrato, $id_contrato, $aplica_dia_ant);
                                        }
                                    } else {
                                        $logger->info("Sin reintegro por novedad");
                                        $valor_interes_banco += $this->calculoInteresBancario($fecha_ini, $fecha_fin, $valor_capital, $tag_ini, $tag_fin, $id_liq_novedad_contrato, $id_contrato, $aplica_dia_ant);
                                    }
                                    $logger->info("Respuesta de calculoInteresBancario: " . $valor_interes_banco);
                                } else {
                                    $logger->info("NO se hace Llamado a calculoInteresBancario");
                                    $logger->info("Fecha ini::" . $fecha_ini);
                                    $logger->info("Fecha fin::" . $fecha_fin);
                                }
                                if ($valor_interes_banco > 0) {
                                    $valor_intereses_banco = $valor_interes_banco;
                                }
                            }
                            $logger->info("FIN Calculo de intereses Bancarios");
                        }

                        /**
                         * Calculo de intereses Moratorios - 20190319
                         * =SI((Fecha legalizacion Hasta+Dias de Legalizacion)<(Fecha de Legalizacion-1);
                          Saldo a Reintegrar*((Fecha de Legalizacion -1)-(Fecha legalizacion Hasta+Dias de Legalizacion))*((6%*2)/360);0) - Hasta 31/10/2018
                         * =SI((Fecha de Legalizacion+1)<(Fecha si Reintegro);
                          Saldo a Reintegrar*((Fecha Reint-1)-(Fecha de Legalizacion+1))*((6%*1,5)/360);0)
                         */
                        if ($aplica_cartera == 1 && $fecha_legalizacion != null) {
                            $logger->info("Calculo de intereses Moratorios");

                            if ($fecha_legalizacion_real == null) {
                                $fecha_legalizacion_real = $fecha_proceso_legal;
                            }

                            /**
                             * Verifica valores de calculo, valor_reintegro un dia antes
                             * Si aplica calculo de intereses mora - 20190404
                             * Se toma el reintegro de la ultima novedad firmada y con relacion activa(novdeb.estado = 1) - 20190415
                             * A la fecha de legalizacion no se le suman los dias en int - 20190531
                             * Se valida que el valor_reintegro_resta solo tome  los valores antes del inicio de calculo - 20211011::LAVILA
                             */
                            $sql = <<<EOD
select 
to_char(to_date('$fecha_legalizacion','yyyy-mm-dd'),'yyyy-mm-dd') as fecha_legalizacion,
to_char(tab1.fecha_caculo_int_banc,'yyyy-mm-dd') as fecha_caculo_int_banc,
to_char(cred.fecha_novedad,'yyyy-mm-dd') as fecha_reintegro,
to_char(cred.fecha_novedad-1,'yyyy-mm-dd') as fecha_reintegro_ant,
nvl(cred.valor_reintegro,0) as valor_reintegro,
nvl(cred.valor_reintegro_resta,0) as valor_reintegro_resta 
                            
from caco_contrato tab1

left join(

    select
    id_contrato,
    min(fecha_novedad) as fecha_novedad,
    sum(valor_reintegro) as valor_reintegro,
    sum(valor_excedente) as valor_excedente,
    
    sum( case when fecha_novedad <= to_date('$fecha_legalizacion_real','yyyy-mm-dd') 
        then valor_reintegro else 0 end ) as valor_reintegro_resta
    
    FROM caco_novedad_reintegro
    
    where
    id_contrato = $id_contrato 
    and tipo_valor in ( 'RE' , 'RC')
    and extract(year from fecha_novedad) || lpad(extract(month from fecha_novedad), 2, '0')  <= $id_anhos || lpad($id_meses, 2, '0')   
    
    group by
    id_contrato

)cred
on cred.id_contrato = tab1.id_contrato
                            
where tab1.id_contrato = $id_contrato 
and tab1.aplica_interes_mora = 1 
EOD;
                            $records = CN_TABLE::executeSQL($sql);
                            if (count($records) > 0) {

                                $valor_reintegro = $records[0]['valor_reintegro'];
                                $valor_reintegro_resta = $records[0]['valor_reintegro_resta'];

                                $fecha_ini = $records[0]['fecha_legalizacion'];
                                $fecha_fin = $fecha_proceso_legal;

                                $valor_capital = $valor_no_ejecutado + $valor_no_reconocido;
                                $valor_capital = $valor_capital_validar = $valor_capital - $valor_reintegro_resta;

                                /**
                                 * Validacion para fecha de credito-reintegro - 20190319
                                 */
//                        if (!is_null($records[0]['fecha_reintegro'])) {
//                            $logger->info("Entro a Validacion para fecha de credito-reintegro");
//                            $fecha_fin = $records[0]['fecha_reintegro'];
//                        }

                                /**
                                 * Validacion para fecha de corte interes mora - 20190524
                                 */
                                if ($fecha_legalizacion_limite != null) {
                                    $logger->info("Entro a Validacion para fecha de corte interes mora");
                                    $fecha_fin = $fecha_legalizacion_limite;
                                }
                                $fecha_legalizacion_limite = $fecha_fin;

                                //Validar valor a capital
                                if ($valor_capital_validar > 0) {
                                    $datetime1 = new DateTime($fecha_ini);
                                    $datetime2 = new DateTime($fecha_fin);
                                    //Validar fecha ini y fin
                                    if ($datetime1 < $datetime2) {
                                        $fecha_ini = $fecha_legalizacion;

                                        /**
                                         * For para Reintegro por novedad - 20200311
                                         */
                                        $sql = <<<EOD
SELECT
id_contrato,
to_char(fecha_novedad,'yyyy-mm-dd') as fecha_novedad,
to_char(fecha_novedad-1,'yyyy-mm-dd') as fecha_novedad_ant,

sum(valor_reintegro) as valor_reintegro,
sum(valor_excedente) as  valor_excedente

FROM caco_novedad_reintegro

where
id_contrato = $id_contrato 
and tipo_valor in ( 'RE' , 'RC')
and fecha_novedad BETWEEN to_date('$fecha_ini','yyyy-mm-dd')  and to_date('$fecha_fin','yyyy-mm-dd')                                     

group by
id_contrato,
fecha_novedad
                                        
order by
id_contrato,
fecha_novedad 
EOD;
                                        $records = CN_TABLE::executeSQL($sql);
                                        if (count($records) > 0) {
                                            $logger->info("Con reintegro por novedad");
                                            $tag_ini = 1;

                                            $fecha_ini_nov = $fecha_ini;
                                            $fecha_fin_nov = $fecha_fin;
                                            $valor_capital_nov = $valor_capital;

                                            //Recorre cada novedad y hace llamado por cada rango de fecha segun novedad reintegro - 20200311
                                            foreach ($records as $value) {

                                                $fecha_novedad = $value['fecha_novedad'];
                                                $fecha_novedad_ant = $value['fecha_novedad_ant'];
                                                $valor_reintegro = $value['valor_reintegro'] - $value['valor_excedente'];

                                                $datetime1 = new DateTime($fecha_novedad);
                                                $datetime2 = new DateTime($fecha_fin);
                                                //Validar fecha ini y fin
                                                if ($datetime1 < $datetime2) {
                                                    $fecha_fin_nov = $fecha_novedad_ant;
                                                }

                                                $logger->info("Llamar calculoInteresMoratorio fecha::" . $fecha_novedad);
                                                $logger->info("Llamar calculoInteresMoratorio valor::" . $valor_reintegro);
                                                $logger->info("Llamar calculoInteresMoratorio valor capital::" . $valor_capital_nov);

                                                $datetime1nov = new DateTime($fecha_ini_nov);
                                                $datetime2nov = new DateTime($fecha_fin_nov);
                                                //Validar saldo mayor que 0 y las fechas aplican
                                                if ($valor_capital_nov > 0 && $datetime1nov <= $datetime2nov) {
                                                    $valor_interes_mora += $this->calculoInteresMoratorio($fecha_ini_nov, $fecha_fin_nov, $valor_capital_nov, $dias_leg, $id_liq_novedad_contrato, $id_contrato, $tag_ini);
                                                    $dias_leg = 0;
                                                }

                                                //nuevo valor a capital
                                                $valor_capital_nov = $valor_capital_nov - $valor_reintegro;
                                                $fecha_ini_nov = $fecha_novedad;
                                                $tag_ini = 0;
                                            }

                                            $logger->info("Llamar calculoInteresMoratorio fecha_ini::" . $fecha_ini_nov);
                                            $logger->info("Llamar calculoInteresMoratorio fecha_fin::" . $fecha_fin);
                                            $logger->info("Llamar calculoInteresMoratorio valor capital::" . $valor_capital_nov);

                                            //Validar saldo mayor que 0
                                            if ($valor_capital_nov > 0) {
                                                $logger->info("Llamado a calculoInteresMoratorio");
                                                $valor_interes_mora += $this->calculoInteresMoratorio($fecha_ini_nov, $fecha_fin, $valor_capital_nov, $dias_leg, $id_liq_novedad_contrato, $id_contrato, $tag_ini);
                                                $logger->info("Respuesta de calculoInteresMoratorio: " . $valor_interes_mora);
                                            }
                                        } else {
                                            $logger->info("Sin reintegro por novedad");

                                            $logger->info("Llamado a calculoInteresMoratorio");
                                            $valor_interes_mora += $this->calculoInteresMoratorio($fecha_ini, $fecha_fin, $valor_capital, $dias_leg, $id_liq_novedad_contrato, $id_contrato, 1);
                                            $logger->info("Respuesta de calculoInteresMoratorio: " . $valor_interes_mora);
                                        }
                                    }
                                    if ($valor_interes_mora > 0) {
                                        $valor_intereses_mora = $valor_interes_mora;
                                    }
                                }
                            }
                        }


                        /**
                         * Calculo de indexacion - 20191021
                         * 
                         * Para indexar se aplica la siguiente fórmula:

                          VR = VH x (IPC actual/IPC inicial)

                          VR: corresponde al valor a reintegrar.
                          VH: Recursos no ejecutados.
                          IPC: Índice de Precios al Consumidor.
                         */
                        if ($fecha_inicial_indexacion != null && $fecha_final_indexacion != null) {
                            $logger->info("Calculo de indexacion");

                            /**
                             * Verifica valores de calculo
                             */
                            $sql = <<<EOD
select 
tab1.*
                            
from caco_contrato tab1

left join(

    select
    id_contrato,
    min(fecha_novedad) as fecha_novedad,
    sum(valor_reintegro) as valor_reintegro,
    sum(valor_excedente) as valor_excedente
    
    FROM caco_novedad_reintegro
    
    where
    id_contrato = $id_contrato 
    and tipo_valor in ( 'RE' )
    
    group by
    id_contrato

)cred
on cred.id_contrato = tab1.id_contrato
                            
where tab1.id_contrato = $id_contrato 
and tab1.aplica_indexacion = 1 
EOD;
                            $records = CN_TABLE::executeSQL($sql);
                            if (count($records) > 0) {

                                $fecha_ini = $fecha_inicial_indexacion;
                                $fecha_fin = $fecha_final_indexacion;

                                $valor_capital = $valor_no_ejecutado;
                                $valor_capital_validar = $valor_capital;


                                //Validar valor a capital
                                if ($valor_capital_validar > 0) {
                                    $datetime1 = new DateTime($fecha_ini);
                                    $datetime2 = new DateTime($fecha_fin);
                                    //Validar fecha ini y fin
                                    if ($datetime1 < $datetime2) {
                                        $logger->info("Llamado a calculoIndexacion");
                                        $valor_interes_mora = $this->calculoIndexacion($fecha_ini, $fecha_fin, $valor_capital, $id_liq_novedad_contrato, $id_contrato);
                                        $logger->info("Respuesta de calculoIndexacion: " . $valor_interes_mora);
                                    }
                                    if ($valor_interes_mora > 0) {
                                        $indexacion = $valor_interes_mora;
                                    }
                                }
                            }
                        }
                    }

                    $fecha_legalizacion_limite = $fecha_proceso_legal;
                    $saldo_pendiente = ($valor_no_ejecutado + $valor_no_reconocido + $indexacion + $valor_intereses_mora + $valor_intereses_banco + $valor_ajuste_indexacion + $valor_ajuste_mora + $valor_ajuste_banco) - ( $no_ejecutados_rein + $no_aprobados_rein + $vlr_interes_ib + $vlr_interes_im + $vlr_interes_ix );

                    //Registro de liq
                    $sql = <<<EOD
insert into caco_liq_novedad_contrato (id_liq_novedad_contrato,id_anhos,id_meses,id_contrato,id_ts_td,doc_soporte,id_tipo_nov_cont,
    fecha_novedad,observaciones,fecha_log,usuario_log,valor_desembolsado,valor_rendimientos,valor_no_ejecutado,valor_no_reconocido,    
        indexacion,valor_intereses_mora,valor_intereses_banco,reintegros_efectuados,no_certificado,destinatario,destinatario_cargo,
            no_radicado,objeto,fecha_legalizacion,dias_leg,obser_indexacion,obser_interes_mora,obser_interes_banco,obser_saldo_pendiente,
                anexo_cetificado,firmado,fecha_firmado,usuario_firmado,valor_ajuste_banco,valor_ajuste_mora,fecha_legalizacion_limite,valor_ajuste_indexacion,aplica_dia_ant,
            fecha_reintegro,no_ejecutados_rein,no_aprobados_rein,vlr_interes_ib,vlr_interes_im,vlr_interes_ix,saldo_pendiente)  
values (null,'$id_anhos','$id_meses','$id_contrato','$id_ts_td','$doc_soporte','$id_tipo_nov_cont',
    last_day(to_date( $id_anhos ||'-'|| $id_meses ||'-01','yyyy-mm-dd')),'$observaciones',trunc(sysdate),'$username','$valor_desembolsado','$valor_rendimientos','$valor_no_ejecutado','$valor_no_reconocido',
        '$indexacion','$valor_intereses_mora','$valor_intereses_banco','$vlr_reintegrado','$no_certificado','$destinatario','$destinatario_cargo',
            '$no_radicado','$objeto',to_date( '$fecha_legalizacion','yyyy-mm-dd'),'$dias_leg','$obser_indexacion','$obser_interes_mora','$obser_interes_banco','$obser_saldo_pendiente',
                '$anexo_cetificado','$firmado',to_date('$fecha_firmado','yyyy-mm-dd'),'$usuario_firmado','$valor_ajuste_banco','$valor_ajuste_mora',to_date('$fecha_legalizacion_limite','yyyy-mm-dd'),'$valor_ajuste_indexacion','$aplica_dia_ant',
            to_date( '$fecha_reintegro','yyyy-mm-dd'),'$no_ejecutados_rein','$no_aprobados_rein','$vlr_interes_ib','$vlr_interes_im','$vlr_interes_ix','$saldo_pendiente') 
EOD;
                    $this->conn->execute($sql);

                    //Consultar liq creada
                    $sql = <<<EOD
SELECT
    *
FROM caco_liq_novedad_contrato
where id_contrato = $id_contrato
and id_anhos = $id_anhos
and id_meses = $id_meses   
EOD;
                    //Ejecutar SQL
                    $records_liq = CN_TABLE::executeSQL($sql);
                    $id_liq_novedad_contrato = $records_liq[0]['id_liq_novedad_contrato'];

                    //Actualizar detalle intereses segun id_liq
                    //Bancarios
                    $sql = <<<EOD
update CACO_LIQ_CALCULO_INT_BANCO set id_liq_novedad_contrato = $id_liq_novedad_contrato 
    where id_contrato = $id_contrato and id_liq_novedad_contrato is null 
EOD;
                    $this->conn->execute($sql);

                    //Moratorios
                    $sql = <<<EOD
update CACO_LIQ_CALCULO_INT_MORA set id_liq_novedad_contrato = $id_liq_novedad_contrato 
    where id_contrato = $id_contrato and id_liq_novedad_contrato is null 
EOD;
                    $this->conn->execute($sql);

                    //Indexacion
                    $sql = <<<EOD
update CACO_LIQ_CALCULO_INDEXACION set id_liq_novedad_contrato = $id_liq_novedad_contrato 
    where id_contrato = $id_contrato and id_liq_novedad_contrato is null 
EOD;
                    $this->conn->execute($sql);
                }
                $i++;
            }

            /*
             * COMMIT DE TODAS LAS TRANSACCIONES
             */
            $this->conn->commit();
            $custom_logger->info(MemcacheHandler::getInstance()->get($progress_key) . " - Termino Mencache.\n");
            MemcacheHandler::getInstance()->set($progress_key, 100);

            $this->status = 0;
            $this->list_data = array();
            $this->logMessage("[caco_liq_carte_contr] Liquidación exitosa");
        } catch (Exception $e) {
            MemcacheHandler::getInstance()->set($progress_key, 100);

            /*
             * ROLLBACK DE TODAS LAS TRANSACCIONES EN CASO DE QUE OCURRA ALGUN ERROR
             */
            $this->conn->rollback();
            $this->status = 1;
            $this->mensajeError = "[caco_liq_carte_contr] Ocurrio un error: " . $e->getMessage();
            $this->list_data = array();
            $this->logMessage("[caco_liq_carte_contr] ERROR!");
            $this->logMessage($e->getMessage());
        }
    }

    /**
     * Calculo por mes de intereses bancarios segun fechas
     * 
     * Calculo segun fechas ini y fin, para el primer mes dias completos, demas meses de 30  - 20201223
     * 
     * aplica_dia_ant - 20210301::LAVILA
      0-Cuando NO se marque el campo el sistema deberá liquidar los intereses con la fecha de legalización registrada.
      1-Cuando se marque el campo el sistema deberá liquidar los intereses un día antes de la fecha de legalización registrada.
      2-Calcula el mes de 30 dias, calculo mensual.
     * 
     * @param type $fecha_ini
     * @param type $fecha_fin
     * @param type $valor_capital
     * @param type $tag_ini - para calculo de fecha ini o tomar mes a 30 dias
     * @param type $tag_fin - para calculo de fecha fin o tomar mes a 30 dias
     */
    public function calculoInteresBancario($fecha_ini, $fecha_fin, $valor_capital, $tag_ini, $tag_fin, $id_liq_novedad_contrato, $id_contrato, $aplica_dia_ant) {

        $this->logMessage("[caco_liq_carte_contr] Calculo datos IB. Desde: " . $fecha_ini . ", Hasta: " . $fecha_fin . ", Valor Capital: " . $valor_capital);
        $valor_interes = 0;

        try {

            $sql = <<<EOD
select 
to_date('$fecha_ini', 'yyyy-mm-dd') as fecha_ini,
to_char(to_date('$fecha_ini', 'yyyy-mm-dd'), 'mm') as fecha_ini_mes,
to_char(to_date('$fecha_ini', 'yyyy-mm-dd'), 'yyyy') as fecha_ini_anho,
to_date('$fecha_fin', 'yyyy-mm-dd') as fecha_fin,
to_char(to_date('$fecha_fin', 'yyyy-mm-dd'), 'mm') as fecha_fin_mes,
to_char(to_date('$fecha_fin', 'yyyy-mm-dd'), 'yyyy') as fecha_fin_anho
from dual 
EOD;

            //ejecuta y obtiene el resultado del sql
            $records = CN_TABLE::executeSQL($sql, true);
            $anho_req = $records[0]['fecha_ini_anho'];
            $mes_req = $records[0]['fecha_ini_mes'];
            $comparar_req = $anho_req . str_pad($mes_req, 2, '0', STR_PAD_LEFT);
            $comparar = $records[0]['fecha_fin_anho'] . str_pad($records[0]['fecha_fin_mes'], 2, '0', STR_PAD_LEFT);

            $sql_total = ' ';
            //echo $comparar_req . '-' . $comparar;
            $this->logMessage("[caco_liq_carte_contr] Comparar: " . $comparar_req . '-' . $comparar);
            $tag = false;

            //Recorre cada mes y coloca un registro por tasa
            while ($comparar_req <= $comparar) {
                //$this->logMessage("[caco_liq_carte_contr] Recorre cada mes y coloca un registro por tasa");

                if ($tag) {
                    $sql_total .= ' union ';
                } else {
                    $tag = true;
                }

                /* Se valida Incidente #9150 - 20190221 */
                $sql = <<<EOD
select 
case when to_char(to_date('$fecha_ini', 'yyyy-mm-dd'), 'yyyymm') = $anho_req$mes_req then to_date('$fecha_ini', 'yyyy-mm-dd') else to_date('$anho_req-$mes_req-01', 'yyyy-mm-dd') end as fecha_ini,
case when to_char(to_date('$fecha_fin', 'yyyy-mm-dd'), 'yyyymm') = $anho_req$mes_req then to_date('$fecha_fin', 'yyyy-mm-dd') else last_day(to_date('$anho_req-$mes_req-01', 'yyyy-mm-dd')) end as fecha_fin,                            
$valor_capital as valor_capital,
nvl((select max(tas.id_tasa_intereses_banc) from caco_tasa_intereses_banc tas where tas.id_anhos = $anho_req and tas.id_meses = $mes_req),0) as id_tasa_intereses_banc,                            
$comparar_req as comparar_req  
from dual 
EOD;

                $ref_siguiente = CN_TABLE::fechaSiguiente($anho_req, $mes_req);

                //variables del request - actualiza por siguientes
                $anho_req = $ref_siguiente['id_anhos'];
                $mes_req = $ref_siguiente['id_meses'];

                //validar ciclo infinito
                if ($anho_req > 2111) {
                    die();
                }

                /*
                 * Cambio por ciclo comparacion fecha - 20120724
                 */
                $mes_req = str_pad($mes_req, 2, '0', STR_PAD_LEFT);
                $comparar_req = $anho_req . $mes_req;

                $sql_total .= $sql;
            }
            //$this->logMessage("[caco_liq_carte_contr] sql_total::" . $sql_total);
            //die();
            //Validar que hay sql para consulta 
            if (strlen($sql_total) > 10) {

                /**
                 * Calcula segun tabla caco_tasa_interes_banc
                 * Para el primer mes se toma dias calendario - 20190329
                 * Se cambia el calculo para que tome en el primer mes los dias con 31 y febrero segun dias - 20190710
                 * Calculo de dias segun mes y año igual ini y fin - 20190813
                 */
                $sql_total_inter = "
select round( sum(nvl(VALOR_INTERES,0)) ) as VALOR_INTERES from(

select

max(int.comparar_req) as comparar_req,
min(int.fecha_ini) as fecha_ini,
max(int.fecha_fin) as fecha_fin,
to_char(int.fecha_fin, 'yyyy') as vigencia,
listagg(to_char(int.fecha_fin, 'mm'), ',') within group (order by mes.id_meses) as mes,
mes.id_meses,
int.valor_capital,
nvl(ti.valor_mensual,0) as tasa_men,
nvl(ti.valor_anual,0) as tasa_anu,
( ( power( (1+(nvl(ti.valor_anual,0)/100)) , (30/360) ) ) - 1 ) * 100 as tasa_dec,
max(int.dias) as dias,
( ( ( int.valor_capital * ( ( power( (1+(nvl(ti.valor_anual,0)/100)) , (30/360) ) ) - 1 ) ) /30) * max(int.dias) ) as valor_interes

from(

    select
    fecha_ini,
    fecha_fin,
    
    --FECHA_RANGO_SIN_TREINTAYUNO(fecha_ini,fecha_fin) as dias,
    case 
    when fecha_ini = to_date('$fecha_ini', 'yyyy-mm-dd') and $tag_ini = 0 and fecha_fin = to_date('$fecha_fin', 'yyyy-mm-dd') then (fecha_fin - fecha_ini) + 1
    when fecha_ini = to_date('$fecha_ini', 'yyyy-mm-dd') and $tag_ini = 0 then ( last_day(fecha_ini) - fecha_ini )+1
    
    when fecha_ini = to_date('$fecha_ini', 'yyyy-mm-dd') and $tag_ini = 1 and fecha_fin  = to_date('$fecha_fin', 'yyyy-mm-dd') then DIAS_RANGO_MES_SIN_TREINTAYUNO(fecha_ini,fecha_fin,extract(month from fecha_ini))  
    when fecha_ini = to_date('$fecha_ini', 'yyyy-mm-dd') and $tag_ini = 1 and fecha_fin != to_date('$fecha_fin', 'yyyy-mm-dd') then 30 - (1 * to_char(fecha_ini, 'dd')) + 1    
    
    when fecha_fin = to_date('$fecha_fin', 'yyyy-mm-dd') and $aplica_dia_ant = 2 then 30
    when fecha_fin = to_date('$fecha_fin', 'yyyy-mm-dd') and $tag_fin = 1 
        then case when (1 * to_char(to_date('$fecha_fin', 'yyyy-mm-dd'), 'dd')) > 30 then 30 else (1 * to_char(to_date('$fecha_fin', 'yyyy-mm-dd'), 'dd')) end  
    else 30 end as dias,
    
    valor_capital,
    id_tasa_intereses_banc,
    comparar_req
    
    from(

        $sql_total
            
    )

)int 

join caco_tasa_intereses_banc ti on int.id_tasa_intereses_banc = ti.id_tasa_intereses_banc
left join meses mes on mes.id_meses = ti.id_meses

group by
to_char(int.fecha_fin, 'yyyy'),
mes.id_meses,
int.valor_capital,
ti.valor_mensual,
ti.valor_anual 

/*order by int.comparar_req*/

)";

                //echo $sql_total;
                //die();
                //ejecuta y obtiene el resultado del sql
                $records = CN_TABLE::executeSQL($sql_total_inter, true);
                if (count($records) == 0) {
                    throw new Exception("Valor del calculo de intereses erroneo.");
                }

                $valor_interes = $records[0]['valor_interes'];

                /**
                 * Guardar calculo por novedad - 20190403
                 * Se cambia el calculo para que tome en el primer mes los dias con 31 y febrero segun dias - 20190710
                 * Calculo de dias segun mes y año igual ini y fin - 20190813
                 */
                $sql_total = <<<EOD
insert into caco_liq_calculo_int_banco (
ID_LIQ_NOVEDAD_CONTRATO,
ID_CONTRATO,
VIGENCIA_MES,
FECHA_INI,
FECHA_FIN,
ID_ANHOS,
ID_MESES,
DIAS,
TASA_ANU,
TASA_MEN,
VALOR_CAPITAL,
VALOR_INTERES)

select

'$id_liq_novedad_contrato' as id_liq_novedad_contrato,
$id_contrato as id_contrato,
tab0.comparar_req as VIGENCIA_MES,
tab0.fecha_ini as FECHA_INI,
tab0.fecha_fin as FECHA_FIN,
tab0.vigencia as ID_ANHOS,
tab0.id_meses as ID_MESES,
tab0.dias as DIAS,
tab0.tasa_anu as TASA_ANU,
tab0.tasa_men as TASA_MEN,
tab0.valor_capital as VALOR_CAPITAL,
tab0.valor_interes as VALOR_INTERES

from(

    select

    max(int.comparar_req) as comparar_req,
    min(int.fecha_ini) as fecha_ini,
    max(int.fecha_fin) as fecha_fin,
    to_char(int.fecha_fin, 'yyyy') as vigencia,
    listagg(to_char(int.fecha_fin, 'mm'), ',') within group (order by mes.id_meses) as mes,
    mes.id_meses,
    int.valor_capital,
    nvl(ti.valor_mensual,0) as tasa_men,
    nvl(ti.valor_anual,0) as tasa_anu,
    ( ( power( (1+(nvl(ti.valor_anual,0)/100)) , (30/360) ) ) - 1 ) * 100 as tasa_dec,
    max(int.dias) as dias,
    ( ( ( int.valor_capital * ( ( power( (1+(nvl(ti.valor_anual,0)/100)) , (30/360) ) ) - 1 ) ) /30) * max(int.dias) ) as valor_interes

    from(

        select
        fecha_ini,
        fecha_fin,
        --FECHA_RANGO_SIN_TREINTAYUNO(fecha_ini,fecha_fin) as dias,
        case 
        when fecha_ini = to_date('$fecha_ini', 'yyyy-mm-dd') and $tag_ini = 0 and fecha_fin = to_date('$fecha_fin', 'yyyy-mm-dd') then (fecha_fin - fecha_ini) + 1
        when fecha_ini = to_date('$fecha_ini', 'yyyy-mm-dd') and $tag_ini = 0 then ( last_day(fecha_ini) - fecha_ini )+1

        when fecha_ini = to_date('$fecha_ini', 'yyyy-mm-dd') and $tag_ini = 1 and fecha_fin  = to_date('$fecha_fin', 'yyyy-mm-dd') then DIAS_RANGO_MES_SIN_TREINTAYUNO(fecha_ini,fecha_fin,extract(month from fecha_ini))  
        when fecha_ini = to_date('$fecha_ini', 'yyyy-mm-dd') and $tag_ini = 1 and fecha_fin != to_date('$fecha_fin', 'yyyy-mm-dd') then 30 - (1 * to_char(fecha_ini, 'dd')) + 1    

        when fecha_fin = to_date('$fecha_fin', 'yyyy-mm-dd') and $aplica_dia_ant = 2 then 30 
        when fecha_fin = to_date('$fecha_fin', 'yyyy-mm-dd') and $tag_fin = 1 
            then case when (1 * to_char(to_date('$fecha_fin', 'yyyy-mm-dd'), 'dd')) > 30 then 30 else (1 * to_char(to_date('$fecha_fin', 'yyyy-mm-dd'), 'dd')) end  
        else 30 end as dias,

        valor_capital,
        id_tasa_intereses_banc,
        comparar_req
                        
        from(

            $sql_total
                        
        )

    )int 

    join caco_tasa_intereses_banc ti on int.id_tasa_intereses_banc = ti.id_tasa_intereses_banc
    left join meses mes on mes.id_meses = ti.id_meses

    group by
    to_char(int.fecha_fin, 'yyyy'),
    mes.id_meses,
    int.valor_capital,
    ti.valor_mensual,
    ti.valor_anual 

)tab0

order by tab0.comparar_req 
EOD;
                $records = CN_TABLE::executeSQL($sql_total, true);
            }
        } catch (Exception $e) {
            $valor_interes = 0;
            $this->logMessage("[caco_liq_carte_contr] ERROR!");
            $this->logMessage($e->getMessage());
        }

        return $valor_interes;
    }

    /**
     * Calculo moratorio por rango de fechas y dias leg
     * 
     * Este interés de mora se calcula en dos etapas, una 1ra etapa se calcula asi:
     * el doble del interes legal civil , (2*6%)/360, desde el momento de la legalización del acta de liquidación o la firmeza del acta unilateral, hasta el 31 de octubre del 2018, y
     * otra etapa desde el 01 de noviembre del 2018, hasta el día del reintegro, al una y media veces del interés legal civil  (1.5*6%)/360
     * 
     * @param type $fecha_ini
     * @param type $fecha_fin
     * @param type $valor_capital
     * @param type $dias_leg
     */
    public function calculoInteresMoratorio($fecha_ini, $fecha_fin, $valor_capital, $dias_leg, $id_liq_novedad_contrato, $id_contrato, $tag_ini) {

        $this->logMessage("[caco_liq_carte_contr] Calculo datos IM. Desde: " . $fecha_ini . ", Hasta: " . $fecha_fin . ", Valor Capital: " . $valor_capital);
        $valor_interes = 0;

        //Suma un dia a la fecha ini, para no tener encuenta el primer dia - 20190531
        //$tag_ini solo para el primer registro - 20201228
        $sql_dia = <<<EOD
select 
to_char( to_date('$fecha_ini', 'yyyy-mm-dd') + $tag_ini , 'yyyy-mm-dd') as fecha_ini
from dual 
EOD;
        $records = CN_TABLE::executeSQL($sql_dia, true);
        $fecha_ini = $records[0]['fecha_ini'];

        try {

            $sql_total = <<<EOD
select 
to_date('$fecha_ini', 'yyyy-mm-dd') + $dias_leg as fecha_ini,
case when to_date('$fecha_fin', 'yyyy-mm-dd') < to_date('2018-10-31', 'yyyy-mm-dd') then to_date('$fecha_fin', 'yyyy-mm-dd') else to_date('2018-10-31', 'yyyy-mm-dd') end as fecha_fin,                            
$valor_capital as valor_capital,
2 as id_tasa_intereses_banc
from dual 
where
to_date('$fecha_ini', 'yyyy-mm-dd') + $dias_leg < to_date('2018-10-31', 'yyyy-mm-dd')

union

select 
case when (to_date('$fecha_ini', 'yyyy-mm-dd') + $dias_leg) >= to_date('2018-11-01', 'yyyy-mm-dd') then to_date('$fecha_ini', 'yyyy-mm-dd') + $dias_leg else to_date('2018-11-01', 'yyyy-mm-dd') end as fecha_ini,
to_date('$fecha_fin', 'yyyy-mm-dd') as fecha_fin,                            
$valor_capital as valor_capital,
1.5 as id_tasa_intereses_banc
from dual 
where
to_date('$fecha_fin', 'yyyy-mm-dd') > to_date('2018-10-31', 'yyyy-mm-dd') 
EOD;
            //$this->logMessage("[caco_liq_carte_contr] sql_total::" . $sql_total);
            //die();
            //Validar que hay sql para consulta 
            if (strlen($sql_total) > 10) {

                /**
                 * Calcula segun SQL
                 * Meses de 30 - 20190403
                 * Incidente #13278,tomar los meses de acuerdo con los días que tenga (28, 30 ó 31) - 20190710
                 */
                $sql_total_inter = "
select round( sum(nvl(VALOR_INTERES,0)) ) as VALOR_INTERES from(

select
int.fecha_ini,
int.fecha_fin,
int.dias,
int.valor_capital,
int.id_tasa_intereses_banc,
(int.valor_capital) * (int.dias) * ((6/100)*int.id_tasa_intereses_banc) / 360 as valor_interes

from(

    select
    fecha_ini,
    fecha_fin,
    --fecha_fin - fecha_ini as dias,
    --FECHA_RANGO_SIN_TREINTAYUNO(fecha_ini,fecha_fin) as dias,
    fecha_fin - fecha_ini as dias,
    valor_capital,
    id_tasa_intereses_banc
    from(

        $sql_total
    )

)int     
    
/*order by int.fecha_ini*/

)";

                //echo $sql_total;
                //die();
                //ejecuta y obtiene el resultado del sql
                $records = CN_TABLE::executeSQL($sql_total_inter, true);
                if (count($records) == 0) {
                    throw new Exception("Valor del calculo de intereses erroneo.");
                }

                $valor_interes = $records[0]['valor_interes'];

                /**
                 * Guardar calculo por novedad - 20190403
                 * Incidente #13278,tomar los meses de acuerdo con los días que tenga (28, 30 ó 31) - 20190710
                 */
                $sql_total = <<<EOD
insert into caco_liq_calculo_int_mora (
ID_LIQ_NOVEDAD_CONTRATO,
ID_CONTRATO,
FECHA_INI,
FECHA_FIN,
DIAS,
TASA_INTERES_BANC,
VALOR_CAPITAL,
VALOR_INTERES)

select

'$id_liq_novedad_contrato' as id_liq_novedad_contrato,
$id_contrato as id_contrato,
tab0.fecha_ini as FECHA_INI,
tab0.fecha_fin as FECHA_FIN,
tab0.dias as DIAS,
tab0.id_tasa_intereses_banc as TASA_INTERES_BANC,
tab0.valor_capital as VALOR_CAPITAL,
tab0.valor_interes as VALOR_INTERES

from(    
   
    select
    int.fecha_ini,
    int.fecha_fin,
    int.dias,
    int.valor_capital,
    int.id_tasa_intereses_banc,
    (int.valor_capital) * (int.dias) * ((6/100)*int.id_tasa_intereses_banc) / 360 as valor_interes

    from(

        select
        fecha_ini,
        fecha_fin,
        --fecha_fin - fecha_ini as dias,
        --FECHA_RANGO_SIN_TREINTAYUNO(fecha_ini,fecha_fin) as dias,
        fecha_fin - fecha_ini as dias,
        valor_capital,
        id_tasa_intereses_banc
        from(

            $sql_total
        )

    )int 

)tab0

order by tab0.FECHA_INI                      
EOD;
                $records = CN_TABLE::executeSQL($sql_total, true);
            }
        } catch (Exception $e) {
            $valor_interes = 0;
            $this->logMessage("[caco_liq_carte_contr] ERROR!");
            $this->logMessage($e->getMessage());
        }

        return $valor_interes;
    }

    /**
     * CalculoIndexacion
     * 
     * @param type $fecha_ini
     * @param type $fecha_fin
     * @param type $valor_capital
     * @param type $id_liq_novedad_contrato
     * @param type $id_contrato
     */
    public function calculoIndexacion($fecha_ini, $fecha_fin, $valor_capital, $id_liq_novedad_contrato, $id_contrato) {


        $this->logMessage("[caco_liq_carte_contr] Calculo datos IX. Desde: " . $fecha_ini . ", Hasta: " . $fecha_fin . ", Valor Capital: " . $valor_capital);
        $valor_interes = 0;

        try {

            $fecha_ini_ind = explode('-', $fecha_ini);
            $fecha_fin_ind = explode('-', $fecha_fin);

            $mes_ini = $fecha_ini_ind[1]; //mes con dos digitos
            $anho_fin = $fecha_ini_ind[0]; //dia con dos digitos

            $mes = $fecha_fin_ind[1]; //mes con dos digitos
            $anho = $fecha_fin_ind[0]; //dia con dos digitos

            if ($mes == 1) {
                $anho = $anho - 1;
                $mes = 12;
            } elseif ($mes <= 12) {
                $mes = $mes - 1;
            }

            /**
             * IPC inicial
             */
            $sql = <<<EOD
SELECT 
ID_IPC,
ID_ANHOS,
ID_MESES,
VALOR,
VALOR_IPC
                    
FROM CA_IPC

WHERE ID_ANHOS='$anho_fin' AND ID_MESES='$mes_ini'                                           
EOD;
            $records = CN_TABLE::executeSQL($sql);
            $ipc_inicial = $records[0]['valor_ipc'];

            /**
             * IPC final
             */
            $sql = <<<EOD
SELECT 
ID_IPC,
ID_ANHOS,
ID_MESES,
VALOR,
VALOR_IPC
                    
FROM CA_IPC

WHERE ID_ANHOS='$anho' AND ID_MESES='$mes'                                            
EOD;
            $records = CN_TABLE::executeSQL($sql);
            $ipc_final = $records[0]['valor_ipc'];


            $tasa_total = $ipc_final / $ipc_inicial;
            $total = ($ipc_final / $ipc_inicial) * $valor_capital;
            $total_indexado = $total - $valor_capital;
            $total_indexado = round($total_indexado, 2);
            $total_meses = CN_TABLE::mesesEntreFechas($fecha_ini, $fecha_fin, $calendario = TRUE);

            $f = CN_TABLE::fechaSistema();

            /*
             * Crea registro en CACO_CALCULO_INDEXACION - 27092019 
             * con el objetivo de calcular la indexación total de contrato a esta fecha.
             */
            $this->logMessage("[caco_liq_carte_contr]  Crea registro en CACO_CALCULO_INDEXACION");
            $sql = <<<EOD
INSERT INTO caco_liq_calculo_indexacion
( ID_LIQ_NOVEDAD_CONTRATO,  
  ID_CONTRATO,
  FECHA_INI,
  FECHA_FIN,
  TASA_TOTAL_IND,
  VALOR_CAPITAL,
  VALOR_IND,
  IPC_INCIAL,
  IPC_FINAL
)
VALUES
(
'$id_liq_novedad_contrato',
$id_contrato,
to_date('$fecha_ini', 'yyyy-mm-dd'),
to_date('$fecha_fin', 'yyyy-mm-dd'),
'$tasa_total',
'$valor_capital',
'$total_indexado',
'$ipc_inicial',
'$ipc_final'
)                
EOD;
            $records = CN_TABLE::executeSQL($sql);

            //redondeo de valores
            $valor_interes = round($total_indexado);
        } catch (Exception $e) {
            $valor_interes = 0;
            $this->logMessage("[caco_liq_carte_contr] ERROR!");
            $this->logMessage($e->getMessage());
        }

        return $valor_interes;
    }

}
