<?php

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

    /**
     * Executes list action
     *
     * @param sfRequest $request A request object
     */
    public function executeList(sfWebRequest $request) {

        $logger = sfContext::getInstance()->getLogger();
        $logger->info("Entro a executeAdd");


        $records = array();
        $arrayConstantes = array();


        /*
         * Abrir conexion transaccion
         */
        $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);
        $arrayConstantes = array();

        /*
         * Manejar Errores
         */
        try {

            /*
             * Obtener consultas glodal
             */
            //Sql
            $sql = <<<EOD
select * from NO_CONSULTA 
EOD;
            //Ejecutar SQL
            $record_consul = CN_TABLE::executeSQL($sql);
            $record_consulta = array();

            if (count($record_consul) > 0) {
                foreach ($record_consul as $key => $value) {
                    $record_consulta[$value['caracter']] = $value;

//                    $this->logMessage("Caracter - " . $value['caracter']);
                }
            }
//            $this->logMessage("Consulta - " . $record_consulta['M']['consulta']);
//            die();

            /**
             * Cargar tabla constantes
             */
            $text = '$con_';
            //Constantes 
            $sql = <<<EOD
Select cons.*, '$text'|| cons.id_constante as reemplazo from no_constante cons 
EOD;
            //Ejecutar SQL
            $records = CN_TABLE::executeSQL($sql);


            //Agrega a un array todas las constantes
            foreach ($records as $value) {

//                foreach ($value as $key => $value2) {
//                    $this->logMessage($key . " - " . $value2);
//                }

                $arrayConstantes[$value['reemplazo']] = $value;
//                $this->logMessage($value['reemplazo'] . "------------------------" . $arrayConstantes[$value['reemplazo']]);
            }

            //PARAMETROS
            $id_periodo_actual = $request['id_periodo'];
            $id_periodo = $periodo = $request['id_periodo_filtro'];
            $id_periodo_ini = $request['id_periodo_ini'];
            $id_periodo_fin = $request['id_periodo_fin'];
            $progress_key = $request['progress_key'] . $request['username'];

            //Funcionario num_doc
            $num_doc = null;
            $whereFuncionarioNumDoc = "";
            if (isset($request['num_doc'])) {
                $num_doc = $request['num_doc'];
                $whereFuncionarioNumDoc = " AND tab0.num_doc = '" . $request['num_doc'] . "'";
            }
            //Funcionario id_tipo_doc 
            $id_tipo_doc = null;
            $whereFuncionarioTipoDoc = "";
            if (isset($request['id_tipo_doc'])) {
                $id_tipo_doc = $request['id_tipo_doc'];
                $whereFuncionarioTipoDoc = " AND tab0.id_tipo_doc = " . $request['id_tipo_doc'];
            }

            $sql = <<<EOD
SELECT * FROM NO_PERIODO WHERE ID_PERIODO = $id_periodo 
EOD;
            $results = CN_TABLE::executeSQL($sql);

            $id_tipo_periodo = $results[0]['id_tipo_periodo'];



//MemcacheHandler::getInstance()->set($progress_key, 100);
//exit();
            /*
             *  Borrar datos anteriores Periodo-Funcionario
             *  Borrar no_liquida_nomina el periodo de retroactivo para cada periodo de ajuste - 20130604
             */
            //Sql
            $sql = <<<EOD
delete from ( 
    select tab0.* from no_liquida_nomina tab0 
    join no_periodo per
    on tab0.id_periodo_ajuste = per.id_periodo
    where tab0.id_periodo = $id_periodo
    and (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = tab0.id_periodo_ajuste) >= (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = $id_periodo_ini)  
    and (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = tab0.id_periodo_ajuste) <= (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = $id_periodo_fin)
    and per.id_tipo_periodo = 5
    $whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
)
EOD;
            //Ejecutar SQL
            //Se deja quemado id-44 periodo de retroactivo inactivos INCI para no liquidar - 20130913
            if ($id_periodo != 44) {
                CN_TABLE::executeSQL($sql);
            }

//            MemcacheHandler::getInstance()->set($progress_key, 10);


            /*
             * Liquida el periodo nuevo de retroactivo
             */
            $sql = <<<EOD
select tab0.*
from no_periodo tab0 
where tab0.id_tipo_periodo = 5
and tab0.id_anhos || lpad(tab0.id_meses,2,'0') >= (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = $id_periodo_ini)  
and tab0.id_anhos || lpad(tab0.id_meses,2,'0') <= (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = $id_periodo_fin)
order by tab0.id_anhos , tab0.id_meses 
EOD;

            $results = CN_TABLE::executeSQL($sql);


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

            /*
             * VALIDA LOS REGISTROS EN LA TABLA NO_ESTADO_FUNC
             * id 6 - tipo periodo retroactivo activos
             * id 7 - tipo periodo retroactivo inactivos
             */
            if ($id_tipo_periodo == 7) {

                /*
                 * Recorre los registros de funcionario - concepto nomina
                 * para ser liquidados
                 */
                $i = 1;
                $nom_conceptos_a_procesar = count($results);

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

                $this->logMessage("[Liquidación Retroactivo Def] nom_conceptos_a_procesar: " . $nom_conceptos_a_procesar);
                $logPath = sfConfig::get('sf_log_dir') . '/liquidacion.log';
                $custom_logger = new sfFileLogger(new sfEventDispatcher(), array('file' => $logPath));

                //For de liquidar por cada periodo entre el rango
                foreach ($results as $resul) {

                    // Guardar un valor en el proceso largo
                    if ($i % $brecha == 0) {
//                    MemcacheHandler::getInstance()->set($progress_key, round(($i / $nom_conceptos_a_procesar) * 100, 0));
                    }

                    $this->logMessage("[Liquidación Retroactivo Def] Existen liquidaciones.");


                    $id_periodo_ajuste = $resul['id_periodo'];
                    //Se deja quemado id-44 periodo de retroactivo inactivos INCI para no liquidar - 20130913
                    if ($id_periodo != 44) {
                        //llamar para cada periodo y liquidar
                        $this->liquidarRetroactivo($id_periodo, $id_periodo_ajuste, $progress_key, $record_consulta, $arrayConstantes, $whereFuncionarioNumDoc, $whereFuncionarioTipoDoc, $id_periodo_actual, $id_periodo_ini, $id_periodo_fin);
//MemcacheHandler::getInstance()->set($progress_key, 100);
//exit();
                    }
                    $i++;

//                break;
                }
            }
//            MemcacheHandler::getInstance()->set($progress_key, 90);


            /*
             * Abrir conexion transaccion
             */
            $this->conn = Doctrine_Manager::getInstance()->getCurrentConnection();
            $this->conn->beginTransaction();

            //COMMIT DE TODAS LAS TRANSACCIONES
            $this->conn->commit();
//            MemcacheHandler::getInstance()->set($progress_key, 100);

            $records = array();

            $this->totalRows = 0;
            $this->startRow = 0;
            $this->endRow = 0;
            $this->list_data = $records;
            $this->logMessage("[Liquidación Retroactivo Def] Liquidación exitosa.");
        } catch (Exception $e) {
//            MemcacheHandler::getInstance()->set($progress_key, 99);
            //ROLLBACK DE TODAS LAS TRANSACCIONES EN CASO DE QUE OCURRA ALGUN ERROR
            $this->conn->rollback();
//            MemcacheHandler::getInstance()->set($progress_key, 100);

            $this->status = 1;
            $this->totalRows = 0;
            $this->startRow = 0;
            $this->endRow = 0;
            $this->mensajeError = "[Liquidación Retroactivo Def] Ocurrio un error: " . $e->getMessage();
            $this->list_data = array();
            $this->logMessage("[Liquidación Retroactivo Def] ERROR!!!");
            $this->logMessage($e->getMessage());
        }
    }

    /**
     * 
     * @param type $id_periodo
     * @param type $id_periodo_ajuste
     * @param type $progress_key
     * @param type $record_consulta
     * @param type $arrayConstantes
     * @param type $whereFuncionarioNumDoc
     * @param type $whereFuncionarioTipoDoc
     */
    public function liquidarRetroactivo($id_periodo, $id_periodo_ajuste, $progress_key, $record_consulta, $arrayConstantes, $whereFuncionarioNumDoc, $whereFuncionarioTipoDoc, $id_periodo_actual, $id_periodo_ini, $id_periodo_fin) {
        $this->logMessage("[Liquidación Retroactivo Def] Entro a liquidarRetroactivo");

        $i = 0;

        /**
         * Manejador de errores
         */
        try {
            /*
             * Abrir conexion transaccion
             */
            $this->conn = Doctrine_Manager::getInstance()->getCurrentConnection();
            $this->conn->beginTransaction();

            /*
             * Tomar valores de NO_AJUSTE_NOMINA
             */
            //Sql
            $sql = <<<EOD
Insert into NO_LIQUIDA_NOMINA (ID_TIPO_DOC,NUM_DOC,ID_CONCEP_NOMINA,ID_PERIODO,VALOR_LIQUIDADO,FECHA_DESDE,FECHA_HASTA,NUM_DIAS,ID_PERIODO_AJUSTE) 

select 
tab0.id_tipo_doc,
tab0.num_doc,
tab0.id_concep_nomina,
tab0.id_periodo,
tab0.valor_ajuste,
 to_date( '01/' || per.id_meses || '/' || per.id_anhos, 'dd/mm/yyyy')  as fecha_desde,
TRUNC(LAST_DAY( to_date(per.id_meses || '/' || per.id_anhos, 'mm/yyyy')  )) as fecha_hasta,
tab0.num_dias,
tab0.ID_PERIODO_AJUSTE
from no_ajuste_nomina tab0
join no_periodo per
on per.id_periodo = tab0.id_periodo 
WHERE tab0.id_periodo = $id_periodo
and tab0.id_periodo_ajuste = $id_periodo_ajuste 
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
EOD;
            //Ejecutar SQL
            CN_TABLE::executeSQL($sql);

            /**
             * Funcionarios con novedad de retiro en el mes del periodo filtrado
             */
            //Sql
            $sql = <<<EOD
select
per.id_anhos as vig_ini,
1 as per_ini,
extract(YEAR FROM nom.fecha_retiro) as vig_fin,
extract(MONTH FROM nom.fecha_retiro) as per_fin, 
tab0.*,
nom.fecha_ingreso,
nom.fecha_termina,
nom.fecha_retiro,
per.id_anhos,
per.id_meses,
per.id_anhos || '-01-01' as fecha_ini,
case when 7 >= per.id_meses
then per.id_anhos - 1 else per.id_anhos end  as anho_ini
from no_novedad_personal tab0

join no_novedades novs
on novs.id_novedad = tab0.id_novedad

join no_tipo_novedad tipnov
on tipnov.id_tipo_novedad = novs.id_tipo_novedad

join no_periodo per
on per.id_periodo = tab0.id_periodo

left join no_nombramiento nom
on tab0.num_doc = nom.num_doc
and tab0.id_tipo_doc = nom.id_tipo_doc
--and nom.estado = 1

where 
tipnov.id_tipo_novedad = 2
and per.id_meses = (select id_meses from no_periodo where id_periodo = $id_periodo_ajuste)   
and per.id_anhos = (select id_anhos from no_periodo where id_periodo = $id_periodo_ajuste) 
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 

and (nom.estado = 1 or
  ( nom.estado = 0 
    and (nom.fecha_retiro
  between to_date('01/'|| (select lpad(id_meses,2,'0') ||'/'||id_anhos from no_periodo where id_periodo = $id_periodo_ajuste) ,'dd/mm/yyyy')
  and trunc(last_day( to_date('01/'|| (select lpad(id_meses,2,'0') ||'/'||id_anhos from no_periodo where id_periodo = $id_periodo_actual) ,'dd/mm/yyyy') ))
  or nom.fecha_retiro = trunc(last_day( to_date('01/'|| (select lpad(id_meses,2,'0') ||'/'||id_anhos from no_periodo where id_periodo = $id_periodo_ajuste) ,'dd/mm/yyyy') )) + 1 )
  )
)
EOD;
            //Ejecutar SQL
            $records = CN_TABLE::executeSQL($sql);

            //Validar si hay funcionarios para liquidación
            if (count($records) > 0) {
                $this->logMessage("[Liquidación Retroactivo Def] Validar si hay funcionarios para liquidación.");

                $id_agrup_concepto = 93;

                /*
                 * Obtener concep_periodo por agrupacion - Orden a liquidar
                 */
                $sql = <<<EOD
select 
* 
from no_agrup_deta
where id_agrup_concepto = $id_agrup_concepto
order by 
orden,
id_agrup_deta 
EOD;
                /*
                  $sql = <<<EOD
                  select distinct
                  tab0.id_concep_nomina,
                  'O' as tipo_valor
                  from no_liquida_nomina tab0

                  join no_periodo per
                  on tab0.id_periodo = per.id_periodo
                  where
                  (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = tab0.id_periodo) >= (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = $id_periodo_ini)
                  and (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = tab0.id_periodo) <= (select id_anhos || lpad(id_meses,2,'0') from no_periodo where id_periodo = $id_periodo_fin)
                  and per.id_tipo_periodo = 5
                  EOD;
                 */          //Ejecutar SQL
                $records_agrup = CN_TABLE::executeSQL($sql);


                /*
                 * Por funcionario 
                 */
                $i = 1;
                $nom_conceptos_a_procesar = count($records);

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

                $this->logMessage("[Liquidación Retroactivo Def] nom_conceptos_a_procesar: " . $nom_conceptos_a_procesar);
                foreach ($records as $value) {

                    // Guardar un valor en el proceso largo
                    if ($i % $brecha == 0) {
                        MemcacheHandler::getInstance()->set($progress_key, round(($i / $nom_conceptos_a_procesar) * 100, 0));
                    }

                    $this->logMessage("[Liquidación Retroactivo Def] Existen liquidaciones.");

                    /*
                     * Datos por record
                     */
                    $num_doc = $value['num_doc'];
                    $id_tipo_doc = $value['id_tipo_doc'];
                    $fecha_ingreso = $value['fecha_ingreso'];
                    $fecha_termina = $value['fecha_termina'];
                    $fecha_retiro = $value['fecha_retiro'];
                    $vig_ini = $value['vig_ini'];
                    $per_ini = $value['per_ini'];
                    $vig_fin = $value['vig_fin'];
                    $per_fin = $value['per_fin'];

                    /*
                     * Calcular los meses a liquidar
                     */
//                    $meses_liq = 0;
                    $meses_liq = $this->mesesLiquidar($id_periodo_ajuste, $num_doc, $id_tipo_doc, $fecha_ingreso, $fecha_termina, $value);
                    $this->logMessage("[Liquidación Retroactivo Def] Meses de Liquidación: " . $meses_liq);

                    /**
                     * Recorrer Agrupaciones
                     */
                    foreach ($records_agrup as $value_agrup) {

                        /*
                         * Variables agrup_concep
                         */
                        $id_concep_nomina = $value_agrup['id_concep_nomina'];
                        $caracter = $value_agrup['tipo_valor'];

                        /*
                         * Calcular los dias a liquidar
                         */
                        $dias_liq_array = $this->diasLiquidar($id_periodo_ajuste, $num_doc, $id_tipo_doc, $fecha_ingreso, $fecha_termina, $value, $id_concep_nomina);

                        $dias_liq = $dias_liq_array['num_dias'];
                        $dias_liq_base = $dias_liq_array['num_dias_base'];
                        $dias_otra_ent = $dias_liq_array['dias_otra_entidad'];

                        $this->logMessage("[Liquidación Retroactivo Def] Dias de Liquidación: " . $dias_liq);

                        $sql = <<<EOD
select
1 as tag,
0 as promedio,
$vig_ini as vig_ini,
$per_ini as per_ini,
$vig_fin as vig_fin,
$per_fin as per_fin,
$meses_liq as meses_liq,
$dias_liq as dias_liq,
$dias_otra_ent as dias_otra_ent,
'$caracter' as caracter,
nvl('$fecha_ingreso', '') as fecha_ingreso,
nvl('$fecha_termina', '') as fecha_termina,
nvl('$fecha_retiro', '') as fecha_retiro,
$dias_liq as num_dias,
$dias_liq_base as num_dias_base,
null as porcentaje,
$num_doc as num_doc,
$id_tipo_doc as id_tipo_doc,
$id_periodo as id_periodo,
$id_periodo as periodo,
$id_concep_nomina as id_concep_nomina
from dual     
EOD;
                        //Ejecutar SQL
                        $recordsLiq = CN_TABLE::executeSQL($sql);

                        /*
                         * Validar registro
                         */
                        if (count($recordsLiq) > 0) {

                            //Liquidar concepto
                            $record_liq = $recordsLiq[0];
                            $this->liquidar($id_periodo, $num_doc, $id_tipo_doc, $id_concep_nomina, $record_liq, $arrayConstantes, $id_periodo_ajuste);
                        } else {
                            /*
                             * Mensaje de error
                             */
                            $mensajeError = "No hay registro para liquidación definitiva. Concepto: " . $id_concep_nomina;

//                            $this->status = 1;
//                            $this->list_data = array();
//                            $this->mensajeError = $mensajeError;
                            $this->logMessage("[Liquidación Retroactivo Def] " . $mensajeError);
                        }
                    }
//                    die();
                    $i++;


                    /*
                     * Solo retefunte
                     * Inicio del proceso de calculo de Retencion en la fuente concepto 2001
                     */
                    //Sql
                    $sql = <<<EOD
select
1 as tag,
0 as meses_liq,
'O' as caracter, 
0 as num_dias, 
0 as num_dias_base,
0 as dias_liq,
$id_periodo as id_periodo,
$id_periodo as periodo,
tab0.*, 
tab0.fecha_desde as fecha_ingreso,
tab0.fecha_hasta as fecha_termina,
tab0.fecha_hasta as fecha_retiro
from no_concepto_func tab0
WHERE 1 = 1 
AND tab0.num_doc = '$num_doc'
AND tab0.id_tipo_doc = $id_tipo_doc 
and tab0.id_concep_nomina = (select id_concep_rete from no_param_concep where id_param_concep = 1)
and tab0.estado = 0
and tab0.actual = 1
order by 
tab0.id_tipo_doc,
tab0.num_doc 
EOD;
                    //Ejecutar SQL
                    $records = CN_TABLE::executeSQL($sql);


                    /*
                     * Recorre los registros de funcionario - concepto nomina
                     * para ser liquidados
                     */
                    foreach ($records as $value) {
                        $this->logMessage("[Liquidación Retroactivo Def] Existen liquidaciones.");

                        $id_periodo = $value['periodo'];
                        $num_doc = $value['num_doc'];
                        $id_tipo_doc = $value['id_tipo_doc'];
                        $id_concep_nomina = $value['id_concep_nomina'];

                        /*
                         * Liquidar periodo-funcionario-concepto nomina
                         */
                        $this->liquidar($id_periodo, $num_doc, $id_tipo_doc, $id_concep_nomina, $value, $arrayConstantes, $id_periodo_ajuste);
                    }
                }

                $this->logMessage("[Liquidación Retroactivo Def] Memcache al 90 porciento");

                //commit de las transacciones
                $this->conn->commit();

                /*
                 * Abrir conexion transaccion
                 */
                $this->conn = Doctrine_Manager::getInstance()->getCurrentConnection();
                $this->conn->beginTransaction();

                //Traer las diferecias de liquida nomina para rango de periodos
                /*
                 * se quita agrupacion de fechas para tener encuenta todos los registros por usuario y concepto - 20140520
                 */
                $sql = <<<EOD

select ID_TIPO_DOC,NUM_DOC,ID_CONCEP_NOMINA,$id_periodo AS ID_PERIODO,
   DIFERENCIA AS VALOR_LIQUIDADO,
       FECHA_DESDE,FECHA_HASTA,NUM_DIAS,ID_PERIODO_AJUSTE

FROM(

select ID_TIPO_DOC,NUM_DOC,ID_CONCEP_NOMINA,FECHA_DESDE,FECHA_HASTA,NUM_DIAS,ID_PERIODO_AJUSTE,VALOR,VALOR_LIQUIDADO,(VALOR - VALOR_LIQUIDADO) AS DIFERENCIA

FROM(

select tab0.*,nvl(tab1.valor_liquidado,0) AS VALOR_LIQUIDADO


from(

select tab0.ID_TIPO_DOC,tab0.NUM_DOC,tab0.ID_CONCEP_NOMINA,
min(tab0.FECHA_DESDE) as FECHA_DESDE, min(tab0.FECHA_HASTA) as FECHA_HASTA,
sum(tab0.NUM_DIAS)AS NUM_DIAS,tab0.ID_PERIODO_AJUSTE,sum(nvl(tab0.VALOR_LIQUIDADO,0)) AS VALOR
                        
from no_liquida_nomina tab0

where tab0.id_periodo = $id_periodo  and tab0.id_periodo_ajuste = $id_periodo_ajuste 

group by tab0.ID_TIPO_DOC,tab0.NUM_DOC,tab0.ID_CONCEP_NOMINA,
--tab0.FECHA_DESDE,tab0.FECHA_HASTA,
tab0.ID_PERIODO_AJUSTE

order by tab0.ID_PERIODO_AJUSTE,tab0.ID_TIPO_DOC,tab0.NUM_DOC,tab0.ID_CONCEP_NOMINA

)tab0                 

left join 
(select tab1.ID_TIPO_DOC,tab1.NUM_DOC,tab1.ID_CONCEP_NOMINA,tab1.ID_PERIODO,sum(nvl(tab1.VALOR_LIQUIDADO,0)) AS VALOR_LIQUIDADO
from no_liquida_nomina tab1
group by tab1.id_tipo_doc,tab1.num_doc,tab1.id_concep_nomina,tab1.id_periodo               
)tab1 ON tab1.id_tipo_doc = tab0.id_tipo_doc and tab1.num_doc = tab0.num_doc and tab1.id_concep_nomina = tab0.id_concep_nomina and tab0.id_periodo_ajuste = tab1.id_periodo

where tab0.num_doc IS NOT NULL
AND tab0.ID_CONCEP_NOMINA!=(select tab2.id_concep_nomina from no_param_concep tab1 
left join no_concep_nomina tab2 ON tab2.id_concep_nomina = tab1.id_concep_rete) 
$whereFuncionarioNumDoc
$whereFuncionarioTipoDoc    
)

)
               
EOD;
                //ejecuta y obtiene el resultado del sql
                $results = CN_TABLE::executeSQL($sql);

                /*
                 * Memcache
                 */
                $i = 1;
                $nom_conceptos_a_procesar = count($results);

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

                foreach ($results as $resul) {

                    // Guardar un valor en el proceso largo
                    if ($i % $brecha == 0) {
                        $por = round(($i / $nom_conceptos_a_procesar) * 100, 0);
                        //MemcacheHandler::getInstance()->set($progress_key, 90 + ($por / 10));
                    }

                    $i++;

                    $id_periodo = $resul['id_periodo'];
                    $id_tipo_doc = $resul['id_tipo_doc'];
                    $num_doc = $resul['num_doc'];
                    $id_concep_nomina = $resul['id_concep_nomina'];
                    $valor = $resul['valor_liquidado'];
                    $fecha_desde = $resul['fecha_desde'];
                    $fecha_desde = explode(' ', $fecha_desde);
                    $fecha_desde = $fecha_desde[0];
                    $fecha_hasta = $resul['fecha_hasta'];
                    $fecha_hasta = explode(' ', $fecha_hasta);
                    $fecha_hasta = $fecha_hasta[0];
                    $num_dias = 'null';
                    if (!is_null($resul['num_dias'])) {
                        $num_dias = $resul['num_dias'];
                    }
                    $id_periodo_ajuste = $resul['id_periodo_ajuste'];

                    $sql = <<<EOD
DELETE FROM NO_LIQUIDA_NOMINA tab0 
    where tab0.id_tipo_doc = $id_tipo_doc and tab0.num_doc = $num_doc  
    and tab0.id_concep_nomina = $id_concep_nomina 
    and tab0.id_periodo_ajuste =  $id_periodo_ajuste and tab0.id_periodo = $id_periodo
EOD;
                    //ejecuta y obtiene el resultado del sql
                    CN_TABLE::executeSQL($sql);

                    /*
                     * Se trae el id de concepto nomina si tiene id de ajuste
                     */
                    $sql = <<<EOD
select case when tab0.id_concep_ajuste is null then tab0.id_concep_nomina 
    else tab0.id_concep_ajuste end as id_concep_nomina
from no_concep_nomina tab0    
where tab0.id_concep_nomina = $id_concep_nomina   
EOD;

                    $results = CN_TABLE::executeSQL($sql);

                    $id_concep_nomina = $results[0]['id_concep_nomina'];

                    //Validar registros mayores a cero
                    if ($valor != 0) {
                        //Crea el nuevo registro en liquida nomina con la diferencia del valor y id de retroactivo
                        $sql = <<<EOD
INSERT INTO NO_LIQUIDA_NOMINA (ID_TIPO_DOC,NUM_DOC,ID_CONCEP_NOMINA,ID_PERIODO,VALOR_LIQUIDADO,FECHA_DESDE,FECHA_HASTA,NUM_DIAS,ID_PERIODO_AJUSTE) 
             VALUES($id_tipo_doc,$num_doc,$id_concep_nomina,$id_periodo,$valor,TO_DATE('$fecha_desde','YYYY-MM-DD'),TO_DATE('$fecha_hasta','YYYY-MM-DD'),
             $num_dias,$id_periodo_ajuste)
EOD;
                        //ejecuta y obtiene el resultado del sql
                        CN_TABLE::executeSQL($sql);
                    }
                }
                //MemcacheHandler::getInstance()->set($progress_key, 99);


                /*
                 * Memcache al 100 porciento
                 */
//                MemcacheHandler::getInstance()->set($progress_key, 100);
                //commit de las transacciones
                $this->conn->commit();
                $this->logMessage("[Liquidación Retroactivo Def] Memcache al 100 porciento");
            } else {
                //commit de las transacciones
                $this->conn->rollback();
            }
        } catch (Exception $exc) {
            $this->logMessage("[Liquidación Retroactivo Def] ERROR!!! liquidarRetroactivo");
            $this->conn->rollback();
        }
    }

    /**
     * Calcular los meses a liquidar
     * @param type $id_periodo
     * @param type $num_doc
     * @param type $id_tipo_doc
     * @param type $fecha_ingreso
     * @param type $fecha_termina
     * @param type $record
     */
    private function mesesLiquidar($id_periodo, $num_doc, $id_tipo_doc, $fecha_ingreso, $fecha_termina, $record) {
        /*
         * Variables de calculo
         */
        $meses = 0;

        /*
         * Prima servicios proporcional - Julio 1 anterior a la fecha de retiro y hasta la misma fecha de retiro
         */
        $anho_ini = $record['anho_ini'];
        $fecha_ini = $anho_ini . '-07-01';

        $date1 = new DateTime($fecha_ini);
        $date2 = new DateTime($fecha_ingreso);

        if ($date2 > $date1) {
            $meses = CN_TABLE::mesesEntreFechas($fecha_ingreso, $fecha_termina, false);
        } else {
            $meses = CN_TABLE::mesesEntreFechas($fecha_ini, $fecha_termina, false);
        }

        /**
         * Calculo de meses
         */
//        $this->logMessage("[Liquidación Retroactivo Def] Meses liquidacion: " . $meses);
        return $meses;
    }

    /**
     * Calcular los dias a liquidar (ausencias no afectan antiguedad) 
     * @param type $id_periodo
     * @param type $num_doc
     * @param type $id_tipo_doc
     * @param type $fecha_ingreso
     * @param type $fecha_termina
     * @param type $record
     * @param type $id_concep_nomina
     * @return int
     */
    private function diasLiquidar($id_periodo, $num_doc, $id_tipo_doc, $fecha_ingreso, $fecha_termina, $record, $id_concep_nomina) {

        /*
         * Variables de calculo
         */
        $dias = 0;
        $dias_base = 0;
        $dias_array = array();
        $dias_kardex = 0;
        $dias_vac = 0;
        $dias_otra_entidad = 0;
        $dias_otra_entidad_liq = 0;

        $fecha_ini_ka = $fecha_ingreso;
        $fecha_fin_ka = $fecha_termina;
        $fecha_retiro = $record['fecha_retiro'];

        /*
         * Calculo de dias por concepto
         */
        //Vacaciones proporcional - Tabla de causacion vacaciones
        if ($id_concep_nomina == 8 || $id_concep_nomina == 9 || $id_concep_nomina == 10) {
            /*
             * Calculo de dias de ausencias
             */
            //Sql
            $sql = <<<EOD
select * from no_causa_vacac  
where 
num_doc =  '$num_doc'  and  id_tipo_doc = $id_tipo_doc 
and to_date('$fecha_termina','yyyy-mm-dd') between fecha_ini and fecha_fin 
EOD;
            //Ejecutar SQL
            $records = CN_TABLE::executeSQL($sql);

            if (count($records) > 0) {

                //Consulta para dias de otros periodos de vacaciones no tomados - 20130620
                $id_causa_vacac = $records[0]['id_causa_vacac'];

                //Sql
                $sql = <<<EOD
select sum(nvl(SALDOS_DIAS,0)) as saldos_dias 
from no_causa_vacac  
where 
num_doc =  '$num_doc'  and  id_tipo_doc = $id_tipo_doc 
and ID_CAUSA_VACAC != $id_causa_vacac
--and TO_DATE('$fecha_termina','yyyy-mm-dd') <= FECHA_FIN 
EOD;
                //Ejecutar SQL
                $records_vac = CN_TABLE::executeSQL($sql);

                $dias_vac = $records_vac[0]['saldos_dias'] * 360 / 15;
                $this->logMessage($records_vac[0]['saldos_dias'] . "[Liquidación Definitiva] dias_vac: " . $dias_vac);


                $fecha_ini = $records[0]['fecha_ini'];
                $fecha_fin = $fecha_termina;

                $dias = CN_TABLE::diasEntreFechas($fecha_ini, $fecha_fin, false);

                //Se toman dias de la tabla de nombramientos que posee hasta el dia que trabaja en fecha_termina
                $dias = $dias + $dias_vac;
            }
        }
        //Prima servicios proporcional - Julio 1 anterior a la fecha de retiro y hasta la misma fecha de retiro
        elseif ($id_concep_nomina == 16) {

            $anho_ini = $record['anho_ini'];
            $fecha_ini = $anho_ini . '-07-01';

            $date1 = new DateTime($fecha_ini);
            $date2 = new DateTime($fecha_ingreso);

            if ($date2 > $date1) {
                $fecha_ini_ka = $fecha_ingreso;
                $dias = CN_TABLE::diasEntreFechas($fecha_ingreso, $fecha_termina, false);
            } else {
                $fecha_ini_ka = $fecha_ini;
                $dias = CN_TABLE::diasEntreFechas($fecha_ini, $fecha_termina, false);
            }
            //Se toman dias de la tabla de nombramientos que posee hasta el dia que trabaja en fecha_termina
            $dias = $dias;
        }
        //Prima de navidad proporcional - Enero 1 a la fecha de retiro
        elseif ($id_concep_nomina == 17 || $id_concep_nomina == 20) {

            $fecha_ini = $record['fecha_ini'];

            $date1 = new DateTime($fecha_ini);
            $date2 = new DateTime($fecha_ingreso);
            //fecha_terminacion
            $date3 = new DateTime($fecha_termina);

            /*
             * Validar que la fecha de terminacion sea mayor a la fecha inicial
             */
            if ($date3 > $date1) {

                /*
                 * Si la fecha de ingreso del funcionario es posterior a la fecha 1 de enero del mismo anho, 
                 * debe tomar solo desde la fecha de ingreso del funcionario
                 */
                if ($date2 > $date1) {
                    $fecha_ini_ka = $fecha_ingreso;
                    $dias = CN_TABLE::diasEntreFechas($fecha_ingreso, $fecha_termina, false);
                } else {
                    $fecha_ini_ka = $fecha_ini;
                    $dias = CN_TABLE::diasEntreFechas($fecha_ini, $fecha_termina, false);
                }
            } else {
                $dias = 0;
            }


            //Se toman dias de la tabla de nombramientos que posee hasta el dia que trabaja en fecha_termina
            $dias = $dias;
        } elseif ($id_concep_nomina == 11) {// se agrega dias para concepto 1011

            /*
             * Registro ultimo de bonificacion
             */
            //Sql
            $sql = <<<EOD
select * from no_bonifica_servicios
where 
num_doc =  '$num_doc'  and  id_tipo_doc = $id_tipo_doc
and to_date('$fecha_termina','yyyy-mm-dd') between fecha_ingresa and fecha_bonifica
order by fecha_bonifica desc 
EOD;
            //Ejecutar SQL
            $records = CN_TABLE::executeSQL($sql);
            if (count($records) > 0) {

                //Consulta para dias de otros periodos de vacaciones no tomados - 20130620
                $fecha_ingresa = $records[0]['fecha_ingresa'];

                $date1 = new DateTime($fecha_ingresa);
                $date2 = new DateTime($fecha_termina);

                if ($date2 > $date1) {
                    $dias = CN_TABLE::diasEntreFechas($fecha_ingresa, $fecha_termina, false);
                }

                $dias = $dias;
            }
        } else {
            $this->logMessage("[Liquidación Retroactivo Def] Id de concepto sin identificar.");
//            $dias = 360;
        }

        $fecha_ini = $fecha_ingreso;
        $fecha_fin = $fecha_termina;

        /**
         * Calculo dias certif otra entidad - 20130702
         */
        //Sql
        $sql = <<<EOD
select 
case when FECHA_DESDE < TO_DATE('$fecha_ini','yyyy-mm-dd') then TO_DATE('$fecha_ini','yyyy-mm-dd') else FECHA_DESDE end as FECHA_INI,
case when FECHA_HASTA > TO_DATE('$fecha_fin','yyyy-mm-dd') then TO_DATE('$fecha_fin','yyyy-mm-dd') else FECHA_HASTA end as FECHA_fin,
case when FECHA_HASTA > TO_DATE('$fecha_fin','yyyy-mm-dd') then TO_DATE('$fecha_fin','yyyy-mm-dd') else FECHA_HASTA end 
- 
case when FECHA_DESDE < TO_DATE('$fecha_ini','yyyy-mm-dd') then TO_DATE('$fecha_ini','yyyy-mm-dd') else FECHA_DESDE end as  DIAS, 

ID_CERTIF_OTRA_ENTIDAD,
ID_TIPO_DOC,
NUM_DOC,
NUM_DOC_SOP,
FECHA_SOPORTE,
OBSERVACIONES,
FECHA_DESDE,
FECHA_HASTA,
NUM_DIAS,
aplica_liquidacion

from NO_CERTIF_OTRA_ENTIDAD

where
(
    FECHA_DESDE between TO_DATE('$fecha_ini','yyyy-mm-dd') and TO_DATE('$fecha_fin','yyyy-mm-dd')
    or 
    FECHA_HASTA between to_date('$fecha_ini','yyyy-mm-dd') and to_date('$fecha_fin','yyyy-mm-dd')
)               
AND num_doc = '$num_doc'
AND id_tipo_doc = $id_tipo_doc
EOD;
        //Ejecutar SQL
        $records = CN_TABLE::executeSQL($sql);

        foreach ($records as $key => $value) {

            $fecha_ini_otra = $value['fecha_ini'];
            $fecha_fin_otra = $value['fecha_fin'];
            $aplica_liq = $value['aplica_liquidacion'];

            if ($aplica_liq == 1) {
                $dias_otra_entidad_liq += CN_TABLE::diasEntreFechas($fecha_ini_otra, $fecha_fin_otra, false);
            }
            $dias_otra_entidad += CN_TABLE::diasEntreFechas($fecha_ini_otra, $fecha_fin_otra, false);
        }

        $this->logMessage("[Liquidación Agrupación] Dias de otra entidad y dias desde fecha_ingreso: " . $dias_otra_entidad);



        /*
         * Claculo de dias de novedad de kardex que afectan antiguedad
         */
        //Se cambio a fechas contando dias habiles - 20130527
        //Sql
        $sql = <<<EOD
select nvl(sum(dias),0) as dias from(
  select 
  dias_habiles_cant( to_date(novka.fecha_ini,'yyyy-mm-dd'), to_date(novka.fecha_fin,'yyyy-mm-dd') ) as dias_hab,
  (to_date(novka.fecha_fin,'yyyy-mm-dd') - to_date(novka.fecha_ini,'yyyy-mm-dd')) + 1  as dias_cal,  
    
   FECHA_RANGO_SIN_TREINTAYUNO(
        case when TO_DATE(NOVKA.FECHA_INI,'yyyy-mm-dd')  < TO_DATE('$fecha_ini_ka','yyyy-mm-dd') 
    then TO_DATE('$fecha_ini_ka','yyyy-mm-dd') else TO_DATE(NOVKA.FECHA_INI,'yyyy-mm-dd') end
    ,
    case when TO_DATE(NOVKA.FECHA_FIN,'yyyy-mm-dd')  > TO_DATE('$fecha_fin_ka','yyyy-mm-dd') 
    then TO_DATE('$fecha_fin_ka','yyyy-mm-dd') else TO_DATE(NOVKA.FECHA_FIN,'yyyy-mm-dd') end
    ) as dias,
                
  novka.* ,
  tipnov.afecta_antigu,
  tipnov.afecta_alimen
  from no_novedad_kardex novka
  join no_tip_nov_ka tipnov 
  on novka.id_tip_nov_ka = tipnov.id_tip_nov_ka
  and tipnov.afecta_antigu = 1 
  where
    (
        novka.fecha_ini between to_date('$fecha_ini_ka','yyyy-mm-dd') and to_date('$fecha_fin_ka','yyyy-mm-dd')
        or novka.fecha_fin between to_date('$fecha_ini_ka','yyyy-mm-dd') and to_date('$fecha_fin_ka','yyyy-mm-dd')
                
        or
        
        TO_DATE('$fecha_ini_ka','yyyy-mm-dd') between novka.fecha_ini and NOVKA.FECHA_FIN
        or 
        TO_DATE('$fecha_ini_ka','yyyy-mm-dd') between novka.fecha_ini and NOVKA.FECHA_FIN
    )
    AND novka.num_doc = '$num_doc'
    AND novka.id_tipo_doc = $id_tipo_doc
    and novka.estado = 1
) 
EOD;
        //Ejecutar SQL
        $recordsKa = CN_TABLE::executeSQL($sql);

        $dias_kardex = $recordsKa[0]['dias'];

        //Restar dias
        $dias_liq = $dias - $dias_kardex;

        /*
         * Calcula de concepto 1008
         */
        if ($id_concep_nomina == 8) {
            $dias_liq = ($dias_liq * 15) / 360;
            $dias_base = round($dias_liq);

            //Dias con festivos
            //Sql
            $sql = <<<EOD
select 
DIAS_HABILES(TO_DATE('$fecha_termina','yyyy-mm-dd'), 1),
DIAS_HABILES( DIAS_HABILES(TO_DATE('$fecha_termina','yyyy-mm-dd'), 1) , $dias_base - 1),
DIAS_HABILES( DIAS_HABILES(TO_DATE('$fecha_termina','yyyy-mm-dd'), 1) , $dias_base - 1) - DIAS_HABILES(TO_DATE('$fecha_termina','yyyy-mm-dd'), 1) + 1 as dias from DUAL
EOD;
            //Ejecutar SQL
            $records = CN_TABLE::executeSQL($sql);

            $dias_liq = $records[0]['dias'];
        }


        /**
         * Calculo de dias
         */
        $this->logMessage("[Liquidación Retroactivo Def] Dias liquidacion: " . $dias_liq . " - Dias Base: " . $dias_base . " - Dias Kardex: " . $dias_kardex);
        $dias_array = array(
            'num_dias' => $dias_liq,
            'dias_otra_entidad' => $dias_otra_entidad - $dias_otra_entidad_liq,
            'dias_otra_entidad_liq' => $dias_otra_entidad_liq,
            'num_dias_base' => $dias_base
        );
        return $dias_array;
    }

    /**
     * Procesa la liquidacion para el periodo, funcionario y concepto nomina
     * @param type $id_periodo
     * @param type $num_doc
     * @param type $id_tipo_doc
     * @param type $id_concep_nomina
     * @param type $record_liq
     * @param type $arrayConstantes
     * @param type $id_periodo_ajuste
     */
    private function liquidar($id_periodo, $num_doc, $id_tipo_doc, $id_concep_nomina, $record_liq, $arrayConstantes, $id_periodo_ajuste) {
        $this->logMessage("[Liquidación Retroactivo Def] Liquidar: periodo " . $id_periodo .
                " - funcionario " . $num_doc . " - concepto nomina " . $id_concep_nomina);

        /**
         * Varibles
         */
        $arrayParametros = array();
        $valor_liquidado = 0;
        $fecha_desde = $record_liq['fecha_ingreso'];
        $fecha_hasta = $record_liq['fecha_termina'];
        $fecha_retiro = $record_liq['fecha_retiro'];
        $num_dias = $record_liq['num_dias'];
        $num_dias_base = $record_liq['num_dias_base'];

        /*
         * Valor Base y porcentaje
         */
        $porcentaje = 'null';
        $valor_base = 'null';

        /*
         *  Cargar fórmulas por concepto
         */
        //Sql
        $sql = <<<EOD
Select * from no_formula WHERE id_concep_nomina = $id_concep_nomina 
EOD;
        //Ejecutar SQL
        $records = CN_TABLE::executeSQL($sql);

        /*
         * Valida si posee formula el concepto
         */
        if (count($records) > 0) {
            $this->logMessage("[Liquidación Retroactivo Def] Entro a calcular Formula.");

            foreach ($records as $value) {

                $formula = $value['formula'];
                $this->logMessage("[Liquidación Retroactivo Def] Formula Inicial: " . $formula);


                /*
                 *  Buscar las constantes, variables, fórmulas(parametros) y agrupaciones que use la fórmula
                 */
                //Reemplazo de constantes            
                $formula = $this->reemplazoConstante($formula, $arrayConstantes);
                $this->logMessage("[Liquidación Retroactivo Def] Formula Constante: " . $formula);

                /*
                 * Reemplaza en la consulta los filtros y valores del SQL, que vienen en el record
                 * Ejemplo: select raz_soc from id_cia where id_cia = $id_cia
                 * Reemplaza $id_cia por el valor en el record
                 */
                if ($record_liq['porcentaje'] == '' || $record_liq['porcentaje'] == null) {
                    $record_liq['porcentaje'] = 0;
                }
                $formula = CN_TABLE::reemplazoConsulta($formula, $record_liq);
                $this->logMessage("[Liquidación Retroactivo Def] Formula consulta los filtros: " . $formula);

                /*
                 * Cambio en la formula de A por (C1+C2)
                 */
                $vars = array();

                CN_TABLE::getVarsInFormula($vars, $formula);

//        var_dump($vars);

                foreach ($vars as $var) {
                    if (substr($var, 0, 1) == 'A') {
                        /*
                         * Cambio de A1 por relacion con los conceptos C1
                         * Ejemplo: 'A1' => '0'
                         */
                        $agrup = $this->reemplazoAgrupacion(substr($var, 1));
                        $this->logMessage("[Liquidación Retroactivo Def] Agrupacion: " . $agrup);

                        $formula = str_replace('{' . $var . '}', $agrup, $formula);
                    }
                }
                $this->logMessage("[Liquidación Retroactivo Def] Formula parametrosFormula y reemplazoAgrupacion: " . $formula);


                /*
                 * Parser de la formula para obtener parametros(variables)
                 * Ejemplo: 'A1' => '0',
                 * 'C1' => '0'
                 */
                $arrayParametros = $this->parametrosFormula($formula);


                /*
                 * Obtener resultados de los parametros(variables)
                 * Ejemplo: $arrayParametros = array(
                 * 'C1' => '0',
                 * 'C2' => '0'
                 * );
                 */
                $arrayParametros = $this->resultadoParametros($arrayParametros, $record_liq);


                /*
                 * Reemplazo de parametros(variables) a la formula
                 * Ejemplo: $arrayParametros = array(
                 * 'C1' => '1100',
                 * 'C2' => '55'
                 * );
                 */
                $formula = $this->reemplazoParametros($formula, $arrayParametros);
                $this->logMessage("[Liquidación Retroactivo Def] Formula Final: " . $formula);


                /*
                 * Ejecutar fórmula
                 * Ejemplo: ( 0 == 0 ? {C1} * $porcentaje : false )
                 * Retorna false  si no cumple con la condicion
                 */
                $formula = str_replace('{', ' ', $formula);
                $formula = str_replace('}', ' ', $formula);
                $result = CN_TABLE::aplicarEval($formula);


                /*
                 * No cumple con la condicion
                 */
//                if ($result === false) {
                if ($result == '-9999' || $result == -9999) {
                    $this->logMessage("[Liquidación Retroactivo Def] Formula No cumple con la condicion: " . $formula);
                    $result = 0;
                }


                /*
                 * Acumulan resultados de liquidacion
                 */
                $valor_liquidado += $result;
                /*
                 * Si es por porcentaje
                 */
                if ($record_liq['porcentaje'] != '' || $record_liq['porcentaje'] != null) {
                    /*
                     * Tipo de formula
                     * V - Valor base 
                     * R - Valor restado 
                     * F - Valor de la fórmula (Uso normal)
                     */
                    if ($value['cod_tipo'] == 'V') {
                        $this->logMessage("[Liquidación Retroactivo Def] Formula CodTipo: " . $value['cod_tipo']);

                        /*
                         * Valor Base y porcentaje
                         */
                        $porcentaje = $record_liq['porcentaje'];
                        $valor_base = ($result * 100) / $record_liq['porcentaje'];
                    }
                }
            }
        } else {

            /**
             * Logica de N
             */
            if ($record_liq['caracter'] == 'N') {
                $this->logMessage("[Liquidación Retroactivo Def] Logica de N - Concepto: " . $id_concep_nomina);

                /*
                 * Resta % (se puede para el valor) 
                 */
                //sumar devengados
                //Sql
                $sql = <<<EOD
select 
nvl(sum(liqnom.valor_liquidado),0) as valor_liquidado  
from no_liquida_nomina liqnom
join no_concep_nomina connom
on liqnom.id_concep_nomina = connom.id_concep_nomina
and connom.operador = 1
where
liqnom.id_periodo = $id_periodo_ajuste
and liqnom.id_tipo_doc = $id_tipo_doc
and liqnom.num_doc = '$num_doc' 
EOD;
                //Ejecutar SQL
                $records_deveng = CN_TABLE::executeSQL($sql);

                if (count($records_deveng) > 0) {

                    $devengado = $records_deveng[0]['valor_liquidado'];

                    //obtener porcentaje de max_ded_noley
                    $devengado_por = ($devengado * $max_ded_noley) / 100;

                    /*
                     * Si es por porcentaje
                     */
                    if ($record_liq['porcentaje'] != '' || $record_liq['porcentaje'] != null) {

                        $valor_logica_n = (0 * $record_liq['porcentaje']) / 100;
                    } else {
                        $valor_logica_n = $record_liq['valor'];
                    }

                    //Validar resta - operar
                    if (($devengado_por - $valor_logica_n - $valor_sumatoria_logica_n) <= 0) {

                        $valor_liquidado = $valor_logica_n;
                        $valor_sumatoria_logica_n += $valor_liquidado;
                    } else {

                        $valor_liquidado = 0;
                    }
                } else {

                    $this->logMessage("[Liquidación Retroactivo Def] No hay valor devengados.");
                    $valor_liquidado = 0;
                }
            } else {
                /*
                 * La liquidación se hacer por 2 espacios temporales:
                 *
                 * - Mensual
                 * En cuyo caso, todos los meses tienen una duración de 30 días
                 * - Por días calendario
                 * En cuyo caso se hace por la cantidad de días especificada en no_concepto_periodo.num_dias
                 * 
                 * Esta especificación, si se hace mensual o usando los días, lo especifica la variable no_concep_nomina.dias_calendario
                 * 
                 * Si se hace una interrupción en un concepto, digamos algún cargo temporal, debe liquidarse el valor del concepto asÍ: 
                 * Ejemplo: $valor = ($valor_liquidado_concepto_mes/30)*$num_dias
                 */

                /*
                 * Si es por porcentaje y diferente de 0
                 */
                if (($record_liq['porcentaje'] != '' || $record_liq['porcentaje'] != null) && $record_liq['porcentaje'] != 0) {
                    $this->logMessage("[Liquidación Retroactivo Def] Calcular porcentaje - " . $record_liq['porcentaje']);


                    //Sql
                    $sql = <<<EOD
select * from no_liquida_nomina 
where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)
and id_periodo = $id_periodo_ajuste
and id_tipo_doc = $id_tipo_doc
and num_doc = '$num_doc' 
EOD;
                    //Ejecutar SQL
                    $records = CN_TABLE::executeSQL($sql);

                    if (count($records) <= 0) {
                        $records[0]['valor_liquidado'] = 0;
                    }

                    //Resultado del calculo de porcentaje
                    $result = ($records[0]['valor_liquidado'] * $record_liq['porcentaje']) / 100;

                    /*
                     * Valor Base y porcentaje
                     */
                    $porcentaje = $record_liq['porcentaje'];
                    $valor_base = $records[0]['valor_liquidado'];
                } else {
                    $this->logMessage("[Liquidación Retroactivo Def] Calcular valor - " . $record_liq['valor']);

                    if (!is_null($record_liq['num_dias'])) {

                        /*
                         * usa_dias_calen
                         */
                        if ($record_liq['usa_dias_calen'] == 0) { //Mensual
                            $num_dias = 30;
                            $num_dias = $record_liq['num_dias']; // ? Revisar
                        } else { //Por días calendario
                            $num_dias = $record_liq['num_dias'];
                        }

                        $result = ($record_liq['valor'] / 30) * $num_dias;
                    } else {
                        $num_dias = 'null';
                        $result = $record_liq['valor'];
                    }
                }

                $valor_liquidado += $result;
            }
        }


        //Dias de proporcionalidad bonificacion por servicios - 20140224
        if ($id_concep_nomina == 11) {
            $valor_liquidado = round(($valor_liquidado * $num_dias) / 360);
        }

        /**
         * Registro de liquida nomina por concepto 
         */
        /*
         * Valida creacion de registro
         */
        if ($valor_liquidado > 0) {

            $this->logMessage("[Liquidación Retroactivo Def] El valor liquidado es: " . $valor_liquidado);

            /*
             * Crear nueva liquidación
             * 
             * Asignar valores encontrados en persona
             */
            //insert into no_liquida_nomina (id_liquida_nomina,id_tipo_doc,num_doc,id_concep_nomina,
            //id_periodo,valor_liquidado,fecha_desde,fecha_hasta,num_dias, valor_base, porcentaje) 
            //values ('9','1','17304849','1','13','257100',to_date('22/11/12','DD/MM/RR'),
            //to_date('22/11/12','DD/MM/RR'),'30');
            //Sql
            $sql = <<<EOD
insert into no_liquida_nomina (id_tipo_doc, num_doc, id_concep_nomina,
        id_periodo,valor_liquidado,fecha_desde,fecha_hasta,num_dias, valor_base, porcentaje, num_dias_base, id_periodo_ajuste ) 
        values ( $id_tipo_doc, '$num_doc', $id_concep_nomina, $id_periodo, round($valor_liquidado), 
        to_date('$fecha_desde','YYYY-MM-DD'), to_date('$fecha_retiro','YYYY-MM-DD'), $num_dias,
            round($valor_base), $porcentaje, $num_dias_base, $id_periodo_ajuste ) 
EOD;
            //Ejecutar SQL
            CN_TABLE::executeSQL($sql);
        } else {

            $this->logMessage("[Liquidación Retroactivo Def] El valor_liquidado es menor a cero.");
        }
    }

    /**
     * Reemplaza en la formula las constantes por valores de la tabla NO_CONSTANTE
     * Ejemplo: $con_1
     * @param type $formula
     * @param type $arrayConstantes
     */
    private function reemplazoConstante($formula, $arrayConstantes) {

        /*
         * Recorrer array de Constantes
         */
        foreach ($arrayConstantes as $key => $value) {

            $formula = str_replace($key, $value['valor'], $formula);
        }

        return $formula;
    }

    /**
     * Reemplaza los parametros(variables) a la formula
     * Ejemplo: $key: C1 / $value: valor - 2+5
     * @param type $formula
     * @param type $arrayParametros
     */
    private function reemplazoParametros($formula, $arrayParametros) {

        /*
         * Recorrer array de Parametros
         */
        foreach ($arrayParametros as $key => $value) {

            $formula = str_replace('{' . $key . '}', $value, $formula);
        }

        return $formula;
    }

    /**
     * Obtener resultados de los parametros(variables)
     * Ejemplo: 'C1' => '0'
     * @param type $arrayParametros
     * @param type $record_liq
     */
    private function resultadoParametros($arrayParametros, $record_liq) {

        /*
         * Recorrer array de Parametros
         */
        foreach ($arrayParametros as $key => $value) {

            //Sacar caracter y numero(id_concep_nomina) para consulta
            $caracter = substr($key, 0, 1);
            $id_concep_nomina = substr($key, 1);
            $this->logMessage("[Liquidación Retroactivo Def] Caracter: " . $caracter . ", numero: " . $id_concep_nomina);

            /*
             * Obtener consulta por caracter
             */
            //Sql
            $sql = <<<EOD
select * from NO_CONSULTA where caracter = '$caracter' 
EOD;
            //Ejecutar SQL
            $record = CN_TABLE::executeSQL($sql);

            //Validar registros SQL
            if (count($record) > 0) {

                $consulta = $record[0]['consulta'];

                //Reemplazo de id_concep_nomina
                $consulta = str_replace('$id_concep_nomina', $id_concep_nomina, $consulta);

                /*
                 * Reemplaza en la consulta los filtros y valores del SQL, que vienen en el record
                 * Ejemplo: select raz_soc from id_cia where id_cia = $id_cia
                 * Reemplaza $id_cia por el valor en el record
                 */
                $consulta = CN_TABLE::reemplazoConsulta($consulta, $record_liq);

                /*
                 * Ejecutar SQL de consulta
                 */
                //Sql
                $sql = <<<EOD
$consulta  
EOD;
                //Ejecutar SQL
                $record = CN_TABLE::executeSQL($sql);

                //Validar registros SQL
                if (count($record) > 0) {
                    $valor = $record[0]['valor'];
                } else {
                    $valor = 0;
                }
            } else {
                $valor = 0;
            }

            $arrayParametros[$key] = $valor;
        }

        return $arrayParametros;
    }

    /**
     * Parser de la formula para obtener parametros(variables)
     * Ejemplo: 'C1' => '0'
     * @param type $formula
     * @param type $arrayParametros
     */
    private function parametrosFormula($formula) {

        $vars = array();

        CN_TABLE::getVarsInFormula($vars, $formula);

        foreach ($vars as $var) {
            $arrayParametros[$var] = 0;
        }

//        var_dump($arrayParametros);
//        exit();
//        $arrayParametros = array(
//            'C1' => '0',
//            'C2' => '0',
//            'T1' => '0',
//            'A1' => '0'
//        );

        return $arrayParametros;
    }

    /**
     * Reemplaza las agrupaciones por los parametros(variables)
     * Ejemplo: A1 -> (+C1-C2-T1)
     * @param type $id_agrup_var
     */
    private function reemplazoAgrupacion($id_agrup_var) {

        $agrup = '( ';

        /*
         * Ejecutar SQL de agrupciones
         */
        //Sql
        $sql = <<<EOD
select 
agru.*,
agru.tipo_valor as caracter
from
no_agrup_deta agru
where agru.id_agrup_concepto = $id_agrup_var  
EOD;
        //Ejecutar SQL
        $records = CN_TABLE::executeSQL($sql);

        /*
         * Recorrer registros 
         */
        foreach ($records as $value) {

            $operador = ($value['operador'] == 1 ? '+' : '-');

            //Concatenar todas las agrupaciones
            $agrup .= $operador . '{' . $value['caracter'] . $value['id_concep_nomina'] . '}';
        }

        $agrup .= ' )';

        return $agrup;
    }

}
