<?php

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

    /**
     * Executes list actions
     * tag. 1 otras nominas 0 nomina del retroactivo
     * tag_retro. 1 cuando debe tomar todo lo del mes incluyendo el retro
     *
     * @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");

        $records = array();
        $arrayConstantes = array();
        /*
         * Variable para optimizar consultas de formulas en las liquidaciones - 20140117
         */
        $vals_calc = 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);

        /*
         * (SGC-1, ANM-2, SGR-3, CYC-4, COL-5, INCI-6, LOCAL-7)
         */
        $array = sfYaml::load(dirname(__FILE__) . '/../../../config/app-gwt.yml');

        $int = 0;
        foreach ($array as $routeName => $routeData) {
            //echo $routeName . "\n";
            if ('entidad_cliente' == $routeName) {
                foreach ($routeData as $key => $value) {
                    //echo $value . "\n";
                    if ($key == 'value') {
                        $entidadCliente = $value;
                    }
                }
            }
            $int++;
        }

        /*
         * Manejar Errores
         */
        try {

            /**
             * Consultar salario minimo
             * Campo porc_incre_salarial - 20150622 
             */
            $salario_minimo = 550000;
            $porc_incre_salarial = 1;
            //Sql
            $sql = <<<EOD
(select nvl(valor_mensual, 0) as valor_mensual, nvl(porc_incre_salarial, 0) as porc_incre_salarial from no_smdlv where vigencia = extract(year from sysdate))   
EOD;
            //Ejecutar SQL
            $record_smlv = CN_TABLE::executeSQL($sql);

            if (count($record_smlv) > 0) {
                $salario_minimo = $record_smlv[0]['valor_mensual'];
                $porc_incre_salarial = $record_smlv[0]['porc_incre_salarial'];
            }

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

            /*
             * Anexo de variables del request para reemplazo en constantes
             */
            $arrayConstantes['$WDIASV'] = '0';
            $arrayConstantes['$WDIAST'] = '0';

            /*
             * Iniciar en 0 dias de liquidacion y totales de vacaciones - 20131216
             */
            $dias_liq = 0;
            $meses_liq = 0;
            $wdiasv_tot = 0;


            //PARAMETROS
            $id_periodo = $periodo = $request['id_periodo_filtro']; //periodo de retroactivo
            $id_periodo_hasta = $request['id_periodo_hasta']; //periodo de confirmacion
            $id_periodo_aju_men = $id_periodo_ini = $request['id_periodo_ini'];
            $id_periodo_fin = $request['id_periodo_fin'];
            $progress_key = $request['progress_key'] . $request['username'];

            //Sql
            $sql = <<<EOD
select 
definitivo as definitivo,
fecha_ini as fecha_desde_tipter,
fecha_fin as fecha_hasta_tipter,
id_anhos as id_anhos_tipter,
id_meses as id_meses_tipter, 
nvl(id_tipo_periodo,0) as id_tipo_periodo 
from no_periodo 
    where id_periodo = $id_periodo 
EOD;
            //Ejecutar SQL
            $record_tipper = CN_TABLE::executeSQL($sql);
            $definitivo = $record_tipper[0]['definitivo'];
            $id_tipo_periodo = $record_tipper[0]['id_tipo_periodo'];
            $id_anhos_tipter = $record_tipper[0]['id_anhos_tipter'];
            $id_meses_tipter = $record_tipper[0]['id_meses_tipter'];
            $fecha_desde_tipter = $record_tipper[0]['fecha_desde_tipter'];
            $fecha_hasta_tipter = $record_tipper[0]['fecha_hasta_tipter'];

            /**
             * Incidente #10608 - 20181213
             */
            if ($definitivo == 1) {
                throw new Exception('El periodo a liquidar ya esta bloqueado.');
            }


            /**
             * se filtran para vacaciones dias de periodos adicionales - 20140613
             * Se cambia metodo por LISTAGG casos CEV - 20190705
             */
            //Sql
            $sql = <<<EOD
select 
--to_char(wm_concat(id_periodo)) as  periodos,
LISTAGG(id_periodo, ',') WITHIN GROUP (ORDER BY id_periodo) as periodos
from no_periodo
where id_anhos = (select id_anhos from no_periodo where id_periodo = $id_periodo_ini )
and id_meses = (select id_meses from no_periodo where id_periodo = $id_periodo_ini )
and id_tipo_periodo in (1 , 2)  
EOD;
            //Ejecutar SQL
            $record_per = CN_TABLE::executeSQL($sql);
            $periodos = $record_per[0]['periodos'];



            /*
             * Variables opcionales
             */
            //tag para buscar las vacaciones de periodos anteriores . solo para el primer periodo de retroactivo - 20140303
            $tag_rn = 0;
            if (isset($request['rownum_'])) {
                $tag_rn = $request['rownum_'];
            }

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

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

            //periodo hasta de personas retiradas - 20130711
            $sql = <<<EOD
SELECT * FROM NO_PERIODO WHERE ID_PERIODO = $id_periodo_hasta 
EOD;
            $results = CN_TABLE::executeSQL($sql);

            $fecha_desde_periodo = $results[0]['fecha_ini'];
            $fecha_desde_periodo = explode(' ', $fecha_desde_periodo);
            $fecha_desde_periodo = $fecha_desde_periodo[0];
            $fecha_hasta_periodo = $results[0]['fecha_fin'];
            $fecha_hasta_periodo = explode(' ', $fecha_hasta_periodo);
            $fecha_hasta_periodo = $fecha_hasta_periodo[0];

//BORRO LOS REGISTROS DE NO_ESTADO_FUNC PARA EL PERIODO RETROACTIVO           
            $sql = <<<EOD
DELETE FROM NO_ESTADO_FUNC tab0 where tab0.periodo = $periodo
$whereFuncionarioNumDoc
$whereFuncionarioTipoDoc                    
EOD;
            //ejecuta y obtiene el resultado del sql
            CN_TABLE::executeSQL($sql);

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

                $sql = <<<EOD
INSERT INTO NO_ESTADO_FUNC (ID_TIPO_DOC,NUM_DOC,ID_DP,ID_ANHOS,ID_MESES,PERIODO,ACTUAL,ID_EA,ID_CEN_OP)

select tab1.id_tipo_doc, tab1.num_doc,tab1.id_dp,
(select id_anhos from no_periodo where id_periodo = $periodo) AS ID_ANHOS,
(select id_meses from no_periodo where id_periodo = $periodo) AS ID_MESES,
$periodo AS ID_PERIODO,1 AS ACTUAL, tab1.id_ea,tab1.id_cen_op

from no_nombramiento_v tab0

left join no_estado_func_v tab1 ON tab1.id_tipo_doc = tab0.id_tipo_doc and tab1.num_doc = tab0.num_doc

where tab1.periodo = (select max(tab3.periodo) from no_estado_func_v tab3 where tab3.id_tipo_doc = tab1.id_tipo_doc and tab3.num_doc = tab1.num_doc)
and tab0.estado = 1                    
$whereFuncionarioNumDoc
$whereFuncionarioTipoDoc                    
EOD;
            } else if ($id_tipo_periodo == 7) {

                /**
                 * Toma encuenta si se retiro el siguiente dia del mes de retiro - 20150622
                 */
                $sql = <<<EOD
INSERT INTO NO_ESTADO_FUNC (ID_TIPO_DOC,NUM_DOC,ID_DP,ID_ANHOS,ID_MESES,PERIODO,ACTUAL,ID_EA,ID_CEN_OP)

select tab1.id_tipo_doc, tab1.num_doc,tab1.id_dp,
(select id_anhos from no_periodo where id_periodo = $periodo) AS ID_ANHOS,
(select id_meses from no_periodo where id_periodo = $periodo) AS ID_MESES,
$periodo AS ID_PERIODO,1 AS ACTUAL, tab1.id_ea,tab1.id_cen_op

from no_nombramiento_v tab0

left join no_estado_func_v tab1 ON tab1.id_tipo_doc = tab0.id_tipo_doc and tab1.num_doc = tab0.num_doc

where tab1.periodo = (select max(tab3.periodo) from no_estado_func_v tab3 where tab3.id_tipo_doc = tab1.id_tipo_doc and tab3.num_doc = tab1.num_doc)
and tab0.fecha_retiro <= (to_date('$fecha_hasta_periodo','YYYY-MM-DD') + 1)               
$whereFuncionarioNumDoc
$whereFuncionarioTipoDoc    
EOD;
            }

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

            /*
              DELETE FROM NO_CONCEPTO_PERIODO tab0
              where tab0.periodo = $periodo
              $whereFuncionarioNumDoc
              $whereFuncionarioTipoDoc
             */
            //Borrar NO_CONCEPTO_PERIODO el periodo de retroactivo para cada periodo de ajuste - 20130604
            $sql = <<<EOD
delete from ( 
    select tab0.* from NO_CONCEPTO_PERIODO tab0 
    join no_periodo per
    on tab0.id_periodo_ajuste = per.id_periodo
    where tab0.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;
            //ejecuta y obtiene el resultado del sql
            CN_TABLE::executeSQL($sql); //Borrar NO_CONCEPTO_PERIODO el periodo de retroactivo para cada periodo de ajuste - 20130604
            //tag para buscar las vacaciones de periodos anteriores . solo para el primer periodo de retroactivo - 20140303
            if ($tag_rn == 1) {
                $sql = <<<EOD
delete from ( 
    select tab0.* from NO_CONCEPTO_PERIODO tab0 
    join no_periodo per
    on tab0.id_periodo_ajuste = per.id_periodo
    where tab0.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 per.id_tipo_periodo != 5
    --and tab0.id_concep_nomina = 7
    $whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
)                   
EOD;
                //ejecuta y obtiene el resultado del sql
                CN_TABLE::executeSQL($sql);

                /*
                 * Borrar los registros del rango de periodo - 20150609
                 */
                $sql = <<<EOD
delete from ( 
    select tab0.* from NO_CONCEPTO_PERIODO tab0 
    join no_periodo per
    on tab0.id_periodo_ajuste = per.id_periodo
    where tab0.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 per.id_tipo_periodo != 5
    $whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
)                   
EOD;
                //ejecuta y obtiene el resultado del sql
                CN_TABLE::executeSQL($sql);
            }

            /**
             * Borrar NO_CONCEPTO_PERIODO el periodo de retroactivo para cada periodo de ajuste - 20130604
             * Borra solo periodos de Nomina Adicional - 20140304
             */
            $sql = <<<EOD
delete from ( 
    select tab0.* from NO_CONCEPTO_PERIODO tab0 
    join no_periodo per
    on tab0.id_periodo_ajuste = per.id_periodo
    where tab0.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 (select id_tipo_periodo from no_periodo where id_periodo = tab0.id_periodo_ajuste) = 2
    $whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
)                   
EOD;
            //ejecuta y obtiene el resultado del sql
            CN_TABLE::executeSQL($sql);

            //TRAIGO LOS PERIODOS QUE SE AFECTAN CON LOS PERIODOS SELECCIONADOS

            $sql = <<<EOD
select tab0.*
from no_periodo tab0 
where tab0.id_tipo_periodo = 1 
    and tab0.id_periodo >= $id_periodo_ini  and tab0.id_periodo <= $id_periodo_fin
order by tab0.fecha_fin 
EOD;

            $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, $por / 10);
                }

                $i++;

                $id_periodo_ajuste = $resul['id_periodo']; //periodo de ajuste - mensual

                /*
                 * Inserta en NO_CONCEPTO_PERIODO los conceptos para cada periodo en el periodo de retroactivo
                 * Los dias pueden ser null, se agrega validacion - 20150611
                 */
                $sql = <<<EOD
INSERT INTO NO_CONCEPTO_PERIODO 
(ID_ANHOS,ID_MESES,PERIODO,ID_TIPO_DOC,NUM_DOC,ID_CONCEP_NOMINA,FECHA_DESDE,
    FECHA_HASTA,VALOR,PORCENTAJE,NUM_DIAS,ID_PERIODO_AJUSTE)

select 
    
tab0.ID_ANHOS,
tab0.ID_MESES,
tab0.PERIODO,
tab0.ID_TIPO_DOC,
tab0.NUM_DOC,
tab0.ID_CONCEP_NOMINA,
tab0.FECHA_DESDE,
tab0.FECHA_HASTA,
tab0.VALOR,
tab0.PORCENTAJE,
tab0.NUM_DIAS,
tab0.ID_PERIODO_AJUSTE

from(

/*Trae concepto_periodo que solo tiene un registro por concepto_nomina y funcionario, tipo concepto 1*/                        
select 
tab0.id_concepto_periodo, tab2.id_meses ID_MESES,tab2.id_anhos ID_ANHOS,
tab2.id_periodo PERIODO,tab0.id_tipo_doc ID_TIPO_DOC,tab0.num_doc,tab0.id_concep_nomina,
tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
tab0.porcentaje AS PORCENTAJE, tab0.num_dias AS NUM_DIAS, tab0.periodo AS ID_PERIODO_AJUSTE,

/* 
COL::Se deja que para los conceptos de la agrupacion 103, se actualice el porcentaje de incremento - 20150622 
Se ajusta para concepto 4001 tome el salario segun mes si es anterior decha desde, tome segun la novedad de ascenso id_dp_ini - 20220510::LAVILA     
Se coloca valdiacion para 4001 si es del año anterior tome el que estaba originalmente, sino si toma el nuevo - 20230607::LAVILA
*/
case 
when EXTRACT(year from tab0.fecha_desde) < (select id_anhos from no_periodo_v where id_periodo = $id_periodo_ajuste)
    and tab0.id_concep_nomina = (select nvl(id_concep_rein,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
    then tab0.valor

when (EXTRACT(year from tab0.fecha_desde) || lpad(EXTRACT(month from tab0.fecha_desde), 2, '0')) < (select anho_mes from no_periodo_v where id_periodo = $id_periodo_ajuste)  
    and tab0.id_concep_nomina = (select nvl(id_concep_rein,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
    then nvl((
        select asignacion_basica from (

            select tab2.asignacion_basica, tab1.num_doc

            from no_novedad_personal tab1
            left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp_ini
            where  tab1.id_periodo in ( 
                select id_periodo from no_periodo_v where anho_mes = (select anho_mes from no_periodo_v where id_periodo = $id_periodo_ajuste)
            )  
            /*Antes era por orden de fecha_terminacion, pero se cambia para tomar la novedad inicial del periodo - 20170616*/    
            order by tab1.num_doc, tab1.fecha_inicial asc, tab1.id_novedad_personal asc

        )tab12 where
        tab12.num_doc = tab0.num_doc
        and rownum = 1
    ),
    (select tab2.asignacion_basica
      from no_estado_func_v tab1
      left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp
      where tab1.rn=1 and tab1.num_doc = tab0.num_doc 
      --and tab1.actual = 1 
      and tab1.periodo = $id_periodo_ajuste)
    )

when tab0.id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1) 
or tab0.id_concep_nomina = (select nvl(id_concep_ajuste,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
or tab0.id_concep_nomina = (select nvl(id_concep_rein,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
then (

  select tab2.asignacion_basica
  from no_estado_func_v tab1
  left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp
  where tab1.rn=1 and tab1.num_doc = tab0.num_doc 
  --and tab1.actual = 1 
  and tab1.periodo = $id_periodo_ajuste

)
when tab0.id_concep_nomina in (select distinct id_concep_nomina from no_agrup_deta where id_agrup_concepto = 103) then round((tab0.valor * $porc_incre_salarial / 100 ) + tab0.valor)
else tab0.valor end AS VALOR,

tab0.valor AS VALOR_ANTERIOR

from no_concepto_periodo tab0
left join no_concep_nomina tab1 ON tab1.id_concep_nomina = tab0.id_concep_nomina  
left join no_periodo tab2 ON tab2.id_periodo = $periodo
left join no_agrup_deta tab3 ON tab3.id_concep_nomina = tab0.id_concep_nomina and tab3.id_agrup_concepto = 0

where tab3.id_agrup_deta IS NULL and tab0.periodo = $id_periodo_ajuste AND(tab1.id_tipo_concepto=1 or tab1.id_tipo_concepto=2)
AND exists 
(

    select comp.num_doc
    from(
        select concep.num_doc,concep.periodo, count(concep.id_concepto_periodo) AS CANTIDAD
        from no_concepto_periodo concep
        where concep.id_concep_nomina = 1
        group by concep.num_doc,concep.periodo
    )
    comp
    where comp.cantidad =1 and comp.periodo = $id_periodo_ajuste and comp.num_doc = tab0.num_doc

)

UNION

/*Trae concepto_periodo que solo tiene un registro por concepto_nomina y funcionario, tipo concepto 1-2*/                        
select tab0.id_concepto_periodo, tab2.id_meses,tab2.id_anhos,tab2.id_periodo,tab0.id_tipo_doc,tab0.num_doc,tab0.id_concep_nomina,tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
tab0.porcentaje AS PORCENTAJE, tab0.num_dias AS NUM_DIAS, tab0.periodo AS ID_PERIODO_AJUSTE,

(
select tab2.asignacion_basica

from no_estado_func_v tab1
left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp
where tab1.rn=1 and tab1.num_doc = tab0.num_doc 
--and tab1.actual = 1 
and tab1.periodo = $id_periodo_ajuste


) * tab0.porcentaje / 100

AS VALOR,tab0.valor AS VALOR_ANTERIOR

from no_concepto_periodo tab0
left join no_concep_nomina tab1 ON tab1.id_concep_nomina = tab0.id_concep_nomina  
left join no_periodo tab2 ON tab2.id_periodo = $periodo
join no_agrup_deta tab3 ON tab3.id_concep_nomina = tab0.id_concep_nomina and tab3.id_agrup_concepto = 0

where tab0.periodo = $id_periodo_ajuste AND(tab1.id_tipo_concepto=1 or tab1.id_tipo_concepto=2)
AND exists 
(

select comp.num_doc

from(

select concep.num_doc,concep.periodo, count(concep.id_concepto_periodo) AS CANTIDAD

from no_concepto_periodo concep


where concep.id_concep_nomina = 1

group by concep.num_doc,concep.periodo
)
comp
where comp.cantidad =1 and comp.periodo = $id_periodo_ajuste and comp.num_doc = tab0.num_doc


)

UNION 

/*Trae concepto_periodo que tienen mas de un registro por concepto_nomina y funcionario, maximo registro de concepto periodo*/     
select tab0.id_concepto_periodo, tab2.id_meses ID_MESES,tab2.id_anhos ID_ANHOS,tab2.id_periodo PERIODO,tab0.id_tipo_doc ID_TIPO_DOC,tab0.num_doc,tab0.id_concep_nomina,tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
tab0.porcentaje AS PORCENTAJE, tab0.num_dias AS NUM_DIAS, tab0.periodo AS ID_PERIODO_AJUSTE,

case when tab0.id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1) 
or tab0.id_concep_nomina = (select nvl(id_concep_ajuste,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
or tab0.id_concep_nomina = (select nvl(id_concep_rein,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
then (
                        
select tab2.asignacion_basica

from no_estado_func_v tab1
left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp
where tab1.rn=1 and tab1.num_doc = tab0.num_doc
--and tab1.actual = 1 
and tab1.periodo=$id_periodo_ajuste


)
else

tab0.valor end

AS VALOR,tab0.valor AS VALOR_ANTERIOR

from no_concepto_periodo tab0
left join no_concep_nomina tab1 ON tab1.id_concep_nomina = tab0.id_concep_nomina  
left join no_periodo tab2 ON tab2.id_periodo = $periodo
left join no_agrup_deta tab3 ON tab3.id_concep_nomina = tab0.id_concep_nomina and tab3.id_agrup_concepto = 0

where tab3.id_agrup_deta IS NULL and tab0.periodo = $id_periodo_ajuste AND(tab1.id_tipo_concepto=1 or tab1.id_tipo_concepto=2)

and tab0.id_concepto_periodo IN(

select max(conc.id_concepto_periodo) ID_CONCEPTO_PERIODO
from no_concepto_periodo conc
where conc.num_doc=tab0.num_doc and conc.periodo = $id_periodo_ajuste
and conc.id_concep_nomina in ( 1 , 401) 

)

AND exists 
(

select comp.num_doc

from(

select concep.num_doc,concep.periodo, count(concep.id_concepto_periodo) AS CANTIDAD

from no_concepto_periodo concep


where concep.id_concep_nomina = 1

group by concep.num_doc,concep.periodo
)
comp
where comp.cantidad >1 and comp.periodo = $id_periodo_ajuste and comp.num_doc = tab0.num_doc


)

UNION 

/*Trae concepto_periodo que tienen mas de un registro por concepto_nomina y funcionario, maximo registro de concepto periodo por concepto de nomina*/ 
select tab0.id_concepto_periodo, tab2.id_meses ID_MESES,tab2.id_anhos ID_ANHOS,tab2.id_periodo PERIODO,tab0.id_tipo_doc ID_TIPO_DOC,tab0.num_doc,tab0.id_concep_nomina,tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
tab0.porcentaje AS PORCENTAJE, tab0.num_dias AS NUM_DIAS, tab0.periodo AS ID_PERIODO_AJUSTE,

case when tab0.id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1) 
or tab0.id_concep_nomina = (select nvl(id_concep_ajuste,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
or tab0.id_concep_nomina = (select nvl(id_concep_rein,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
then (
select tab2.asignacion_basica

from no_estado_func_v tab1
left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp
where tab1.rn=1 and tab1.num_doc = tab0.num_doc
--and tab1.actual = 1 
and tab1.periodo=$id_periodo_ajuste


)
else

tab0.valor end

AS VALOR,tab0.valor AS VALOR_ANTERIOR

from no_concepto_periodo tab0


left join no_concep_nomina tab1 ON tab1.id_concep_nomina = tab0.id_concep_nomina  

left join no_periodo tab2 ON tab2.id_periodo = $periodo

left join no_agrup_deta tab3 ON tab3.id_concep_nomina = tab0.id_concep_nomina and tab3.id_agrup_concepto = 0

where tab3.id_agrup_deta IS NULL and tab0.periodo = $id_periodo_ajuste AND(tab1.id_tipo_concepto=1 or tab1.id_tipo_concepto=2)

and tab0.id_concepto_periodo IN(

select max(conc.id_concepto_periodo) ID_CONCEPTO_PERIODO

from no_concepto_periodo conc

where conc.num_doc=tab0.num_doc and conc.id_concep_nomina = tab0.id_concep_nomina and conc.periodo = $id_periodo_ajuste

)

AND exists 
(

select comp.num_doc

from(

select concep.num_doc,concep.periodo, count(concep.id_concepto_periodo) AS CANTIDAD

from no_concepto_periodo concep


where concep.id_concep_nomina = 1

group by concep.num_doc,concep.periodo
)
comp
where comp.cantidad >1 and comp.periodo = $id_periodo_ajuste and comp.num_doc = tab0.num_doc


)

UNION



/*Trae concepto_periodo que tienen mas de un registro por concepto_nomina y funcionario, toma el valor de la novedad segun el cargo*/ 
select tab0.id_concepto_periodo, tab2.id_meses ID_MESES,tab2.id_anhos ID_ANHOS,tab2.id_periodo PERIODO,tab0.id_tipo_doc ID_TIPO_DOC,tab0.num_doc,tab0.id_concep_nomina,tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
tab0.porcentaje AS PORCENTAJE, tab0.num_dias AS NUM_DIAS, tab0.periodo AS ID_PERIODO_AJUSTE,

case when tab0.id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1) 
or tab0.id_concep_nomina = (select nvl(id_concep_ajuste,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
or tab0.id_concep_nomina = (select nvl(id_concep_rein,id_concep_nomina) as id_concep_nomina from no_concep_nomina where id_concep_nomina = (select id_concep_basica from no_param_concep where id_param_concep = 1)) 
then (
  select asignacion_basica from (
    
        select tab2.asignacion_basica, tab1.num_doc
        
        from no_novedad_personal tab1
        left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp_ini
        where  tab1.id_periodo in ( 
            select id_periodo from no_periodo_v where anho_mes = (select anho_mes from no_periodo_v where id_periodo = $id_periodo_ajuste)
        )  
        /*Antes era por orden de fecha_terminacion, pero se cambia para tomar la novedad inicial del periodo - 20170616*/    
        order by tab1.num_doc, tab1.fecha_inicial asc, tab1.id_novedad_personal asc
    
    )tab12 where
    tab12.num_doc = tab0.num_doc
    and rownum = 1
)
else

tab0.valor end

AS VALOR,tab0.valor AS VALOR_ANTERIOR

from no_concepto_periodo tab0
left join no_concep_nomina tab1 ON tab1.id_concep_nomina = tab0.id_concep_nomina  
left join no_periodo tab2 ON tab2.id_periodo = $periodo
left join no_agrup_deta tab3 ON tab3.id_concep_nomina = tab0.id_concep_nomina and tab3.id_agrup_concepto = 0

where tab3.id_agrup_deta IS NULL and tab0.periodo = $id_periodo_ajuste AND(tab1.id_tipo_concepto=1 or tab1.id_tipo_concepto=2)

and tab0.id_concepto_periodo IN(

select MIN(conc.id_concepto_periodo) ID_CONCEPTO_PERIODO

from no_concepto_periodo conc

where conc.num_doc=tab0.num_doc and conc.id_concep_nomina = tab0.id_concep_nomina and conc.periodo = $id_periodo_ajuste

)

AND exists 
(

select comp.num_doc

from(

select concep.num_doc,concep.periodo, count(concep.id_concepto_periodo) AS CANTIDAD

from no_concepto_periodo concep


where concep.id_concep_nomina = 1

group by concep.num_doc,concep.periodo
)
comp
where comp.cantidad >1 and comp.periodo = $id_periodo_ajuste and comp.num_doc = tab0.num_doc


)



UNION

select tab0.id_concepto_periodo, tab2.id_meses ID_MESES,tab2.id_anhos ID_ANHOS,tab2.id_periodo PERIODO,tab0.id_tipo_doc ID_TIPO_DOC,tab0.num_doc,tab0.id_concep_nomina,tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
tab0.porcentaje AS PORCENTAJE, tab0.num_dias AS NUM_DIAS, tab0.periodo AS ID_PERIODO_AJUSTE,

(
select tab2.asignacion_basica

from no_estado_func_v tab1
left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp
where tab1.rn=1 and tab1.num_doc = tab0.num_doc 
--and tab1.actual = 1 
and tab1.periodo=$id_periodo_ajuste


)*tab0.porcentaje / 100

AS VALOR,tab0.valor AS VALOR_ANTERIOR

from no_concepto_periodo tab0


left join no_concep_nomina tab1 ON tab1.id_concep_nomina = tab0.id_concep_nomina  

left join no_periodo tab2 ON tab2.id_periodo = $periodo

join no_agrup_deta tab3 ON tab3.id_concep_nomina = tab0.id_concep_nomina and tab3.id_agrup_concepto = 0

where tab0.periodo = $id_periodo_ajuste AND(tab1.id_tipo_concepto=1 or tab1.id_tipo_concepto=2)

and tab0.id_concepto_periodo IN(

select max(conc.id_concepto_periodo) ID_CONCEPTO_PERIODO

from no_concepto_periodo conc

where conc.num_doc=tab0.num_doc and conc.id_concep_nomina = tab0.id_concep_nomina and conc.periodo = $id_periodo_ajuste

)

AND exists 
(

select comp.num_doc

from(

select concep.num_doc,concep.periodo, count(concep.id_concepto_periodo) AS CANTIDAD

from no_concepto_periodo concep


where concep.id_concep_nomina = 1

group by concep.num_doc,concep.periodo
)
comp
where comp.cantidad >1 and comp.periodo = $id_periodo_ajuste and comp.num_doc = tab0.num_doc


)
                        
--order by tab0.id_concepto_periodo                        

UNION
    --vacaciones de un periodo anterior para el primer periodo de retroactivo, anho pasado, filtro concepto 1007 - 20140303
    select 
    tab0.id_novedad_vac, 
    (select id_meses from no_periodo where id_periodo = $periodo) AS ID_MESES,
    (select id_anhos from no_periodo where id_periodo = $periodo) AS ID_ANHOS,
    $periodo as PERIODO,
    tab0.id_tipo_doc ID_TIPO_DOC,
    tab0.num_doc,
    tab0.id_concep_nomina,

    tab0.fecha_ini AS FECHA_DESDE, tab0.fecha_fin AS FECHA_HASTA,

    0 AS PORCENTAJE, 
    tab0.num_dias AS NUM_DIAS, 
    tab0.id_periodo AS ID_PERIODO_AJUSTE,
    0 AS VALOR,
    0 AS VALOR_ANTERIOR

    from(


        select 
        nov.*,
        convac.id_concep_nomina,
        nov.fecha_fin - (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) + 1 as num_dias

        from no_novedad_vac nov

        join no_periodo_v perv
        on perv.id_periodo = nov.id_periodo

        join no_concep_vac convac
        on nov.id_tipo_nov_vac = convac.id_tipo_nov_vac

        where nov.fecha_fin >= (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        /*between (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) 
          and (select per.fecha_fin from no_periodo per where per.id_periodo = $id_periodo_ajuste)*/
        and nov.fecha_ini < (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) 
                        
        and perv.id_anhos != (select per.id_anhos from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        and perv.id_meses != (select per.id_meses from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        AND convac.id_concep_nomina = (select no_param_concep.id_concep_vacac from no_param_concep where no_param_concep.id_param_concep = 1)

    )tab0                        
                        
UNION
                        
    --vacaciones de un periodo anterior para el primer periodo de retroactivo. solo dias para 1007- 20140303
    select 
    tab0.id_novedad_vac, 
    (select id_meses from no_periodo where id_periodo = $periodo) AS ID_MESES,
    (select id_anhos from no_periodo where id_periodo = $periodo) AS ID_ANHOS,
    $periodo as PERIODO,
    tab0.id_tipo_doc ID_TIPO_DOC,
    tab0.num_doc,
    tab0.id_concep_nomina,

    tab0.fecha_ini AS FECHA_DESDE, tab0.fecha_fin AS FECHA_HASTA,

    0 AS PORCENTAJE, 
    case when tab0.id_concep_nomina = (select no_param_concep.id_concep_vacac from no_param_concep where no_param_concep.id_param_concep = 1) then tab0.num_dias else 0 end AS NUM_DIAS, 
    tab0.id_periodo AS ID_PERIODO_AJUSTE,
    0 AS VALOR,
    0 AS VALOR_ANTERIOR

    from(


        select 
        nov.*,
        convac.id_concep_nomina,
        nov.fecha_fin - nov.fecha_ini + 1 as num_dias

        from no_novedad_vac nov

        join no_periodo_v perv
        on perv.id_periodo = nov.id_periodo

        join no_concep_vac convac
        on nov.id_tipo_nov_vac = convac.id_tipo_nov_vac

        where nov.fecha_fin >= (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        /*between (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) 
          and (select per.fecha_fin from no_periodo per where per.id_periodo = $id_periodo_ajuste)*/
        and nov.fecha_ini >= (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) 
                        
        and perv.id_anhos != (select per.id_anhos from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        and perv.id_meses != (select per.id_meses from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        --AND convac.id_concep_nomina = (select no_param_concep.id_concep_vacac from no_param_concep where no_param_concep.id_param_concep = 1)

    )tab0                        
                        
UNION



select tab0.id_concepto_periodo, tab2.id_meses ID_MESES,tab2.id_anhos ID_ANHOS,tab2.id_periodo PERIODO,tab0.id_tipo_doc ID_TIPO_DOC,tab0.num_doc,tab0.id_concep_nomina,tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
tab0.porcentaje AS PORCENTAJE, tab0.num_dias AS NUM_DIAS, tab0.periodo AS ID_PERIODO_AJUSTE,


(
  select asignacion_basica from (
    
        select tab2.asignacion_basica, tab1.num_doc
        
        from no_novedad_personal tab1
        left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp_ini
        where  tab1.id_periodo = $id_periodo_ajuste
        order by tab1.num_doc, tab1.fecha_terminacion desc
    
    )tab12 where
    tab12.num_doc = tab0.num_doc
    and rownum = 1

)*tab0.porcentaje / 100



AS VALOR,tab0.valor AS VALOR_ANTERIOR

from no_concepto_periodo tab0
left join no_concep_nomina tab1 ON tab1.id_concep_nomina = tab0.id_concep_nomina  
left join no_periodo tab2 ON tab2.id_periodo = $periodo
join no_agrup_deta tab3 ON tab3.id_concep_nomina = tab0.id_concep_nomina and tab3.id_agrup_concepto = 0

where tab0.periodo = $id_periodo_ajuste AND(tab1.id_tipo_concepto=1 or tab1.id_tipo_concepto=2)

and tab0.id_concepto_periodo IN(

select MIN(conc.id_concepto_periodo) ID_CONCEPTO_PERIODO

from no_concepto_periodo conc

where conc.num_doc=tab0.num_doc and conc.id_concep_nomina = tab0.id_concep_nomina and conc.periodo = $id_periodo_ajuste

)

AND exists 
(

select comp.num_doc

from(

select concep.num_doc,concep.periodo, count(concep.id_concepto_periodo) AS CANTIDAD

from no_concepto_periodo concep


where concep.id_concep_nomina = 1

group by concep.num_doc,concep.periodo
)
comp
where comp.cantidad >1 and comp.periodo = $id_periodo_ajuste and comp.num_doc = tab0.num_doc


)

--order by tab0.id_concepto_periodo

)tab0 
                        
                        
join no_estado_func tab3 ON tab3.id_tipo_doc = tab0.id_tipo_doc 
    and tab3.num_doc = tab0.num_doc and tab3.periodo = $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
)
and nvl(tab0.num_dias,0) >= 0                        
$whereFuncionarioNumDoc
$whereFuncionarioTipoDoc    
ORDER BY tab0.NUM_DOC, tab0.ID_CONCEP_NOMINA, tab0.id_periodo_ajuste, tab0.id_concepto_periodo         
                    
EOD;

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



            /**
             * OJO::Quemado porcentaje de aumento
             * Actualizar el valor base de conceptos de novedad kardex - 20150609
             */
            //(SGC-1, ANM-2, SGR-3, CYC-4, COL-5, INCI-6, LOCAL-7)
            if ($entidadCliente == 2 || $entidadCliente == 4 || $entidadCliente == 7) {
                $sql = <<<EOD
UPDATE no_concepto_periodo tab0 set tab0.valor = nvl(tab0.valor,0) + round((nvl(tab0.valor,0)*$porc_incre_salarial/100),0) 
where tab0.id_concep_nomina in (select id_concep_nomina from no_concep_ka)
and tab0.periodo = $periodo
and tab0.id_periodo_ajuste = $id_periodo_ini                        
$whereFuncionarioNumDoc
$whereFuncionarioTipoDoc                        
EOD;
                //ejecuta y obtiene el resultado del sql
                CN_TABLE::executeSQL($sql);

                /*
                 * Borrar registros creados de novedad incapacidad, si no corresponde al rango de fecha(este anho) - 20150609
                 */
                $sql = <<<EOD
delete from no_concepto_periodo tab0
where tab0.id_concepto_periodo not in ( 
    select 
    conper.id_concepto_periodo
    from no_concepto_periodo conper
    left join no_novedad_kardex novka on novka.id_tipo_doc = conper.id_tipo_doc and novka.num_doc = conper.num_doc
    and novka.id_periodo = conper.id_periodo_ajuste
    left join no_tip_nov_ka tipka on tipka.id_tip_nov_ka = novka.id_tip_nov_ka

    where 
    conper.id_concep_nomina in (select id_concep_nomina from no_concep_ka)
    and conper.periodo = $periodo
    and conper.id_periodo_ajuste = $id_periodo_ini
    and novka.estado = 1
    and tipka.causa_liquidacion = 1
    and novka.fecha_ini >= ( to_date( (select id_anhos from no_periodo where id_periodo = $periodo) || '-01-01' ,'yyyy-mm-dd')  )
)                     
$whereFuncionarioNumDoc
$whereFuncionarioTipoDoc    
and tab0.periodo = $periodo
and tab0.id_periodo_ajuste = $id_periodo_ini  
and tab0.id_concep_nomina in (select id_concep_nomina from no_concep_ka)                           
EOD;
                //ejecuta y obtiene el resultado del sql
                CN_TABLE::executeSQL($sql);
            }



            /*
             * Traer valores nuevos para id_concep_nomina 14 horas extras           
             * Se pone en horas_mes en 240 para periodo 201304 - 20130606
             * Se valida que el concepto de nomina corresponda al del tipo de hora extra - 20150618
             */
            $sql = <<<EOD
select 
nvl(tab1.valor,0) as valor_new,
tab0.*
from no_concepto_periodo tab0

join (      

      select 
      id_concep_nomina,
      id_periodo,
      id_tipo_doc,
      num_doc,
      round(sum((valor / horas_mes) * factor * cantidad) , 2) as valor
      
      from(
      
          select 
          tip.id_concep_nomina,
          lot.id_periodo,
          lot.id_anhos,
          lot.id_meses,
          ext.*,
          tip.factor,
          (select sum(estado.valor)
                  from no_concepto_func estado
                  join no_param_concep parametros on parametros.id_concep_basica = estado.id_concep_nomina
                  where estado.estado=1 and estado.actual=1 and estado.id_tipo_doc = ext.id_tipo_doc and estado.num_doc = ext.num_doc ) as valor,
          
          case when lot.id_anhos = 2013 and lot.id_meses = 4 then 240 else (select sum(nvl(no_nombramiento_v.horas_mes,0)) 
          from no_nombramiento_v
          where
          id_tipo_doc = ext.id_tipo_doc
          and num_doc = ext.num_doc
          and rn = 1) end
          as horas_mes        
          
          from no_hr_extra ext
          
          join no_tipo_hr_extra tip
          on tip.id_tipo_hr_extra = ext.id_tipo_hr_extra
          
          join(
              select 
              lot.*,
              per.id_anhos,
              per.id_meses
              from no_lote_hr_extra lot
              left join no_periodo per
              on per.id_periodo = lot.id_periodo
              where 
              lot.id_periodo >= $id_periodo_ini  and lot.id_periodo <= $id_periodo_fin
          )lot
          on ext.id_lote_hr_extra = lot.id_lote_hr_extra
          
          /*
          where ext.id_lote_hr_extra in (
              select 
              lot.id_lote_hr_extra
              from no_lote_hr_extra lot
              where 
              lot.id_periodo >= $id_periodo_ini  and lot.id_periodo <= $id_periodo_fin
          )
          */
      )
      
      group by 
      id_concep_nomina,
      id_tipo_doc,
      num_doc,
      id_periodo


)tab1
on tab1.id_tipo_doc = tab0.id_tipo_doc and tab1.num_doc = tab0.num_doc
and tab1.id_periodo = tab0.id_periodo_ajuste
and tab1.id_concep_nomina = tab0.id_concep_nomina

where 
tab0.periodo = $periodo
and tab0.id_concep_nomina in (select distinct id_concep_nomina from no_tipo_hr_extra)            
EOD;
            //ejecuta y obtiene el resultado del sql
            $records_hr = CN_TABLE::executeSQL($sql);

            /*
             * Actualizar concep_periodo horas
             */
            foreach ($records_hr as $value_hr) {

                $valor_new = round($value_hr['valor_new']);
                $id_concepto_periodo = $value_hr['id_concepto_periodo'];

                //actualizar valores nuevos para id_concep_nomina 14 horas extras           
                $sql = <<<EOD
update NO_CONCEPTO_PERIODO set valor =  $valor_new
    where id_concepto_periodo = $id_concepto_periodo
EOD;
                //ejecuta y obtiene el resultado del sql
                CN_TABLE::executeSQL($sql);
            }

            // Borrar NO_CONCEPTO_PERIODO retefuente el periodo de retroactivo para cada periodo de ajuste - 20130604
            $sql = <<<EOD
delete from NO_CONCEPTO_PERIODO tab0 
                    
where 
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
)     
and tab0.periodo = $periodo    
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc                        
EOD;
            //ejecuta y obtiene el resultado del sql
            CN_TABLE::executeSQL($sql);


            /**
             * RETENCION EN LA FUENTE - 20130604
             * Verificar que el funcionario este en no_estado_func_v para el periodo - 20150619
             */
            $sql = <<<EOD
INSERT INTO NO_CONCEPTO_PERIODO 
(ID_MESES,ID_ANHOS,PERIODO,ID_TIPO_DOC,NUM_DOC,ID_CONCEP_NOMINA,FECHA_DESDE,FECHA_HASTA,VALOR,PORCENTAJE,
    NUM_DIAS,ID_PERIODO_AJUSTE)        
select tab2.id_meses ID_MESES,tab2.id_anhos ID_ANHOS,tab2.id_periodo PERIODO,tab0.id_tipo_doc ID_TIPO_DOC,
    tab0.num_doc,tab0.id_concep_nomina,tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
tab0.VALOR as VALOR, tab0.porcentaje AS PORCENTAJE, 30 AS NUM_DIAS, tab2.id_periodo AS ID_PERIODO_AJUSTE

from no_concepto_func tab0
left join no_periodo tab2 ON tab2.id_periodo = $periodo
where tab0.actual = 1 and tab0.estado = 1
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

)
and tab0.porcentaje>0
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
and tab0.num_doc in ( select distinct num_doc from no_estado_func_v where periodo = $periodo )
                  
EOD;
            //ejecuta y obtiene el resultado del sql
            CN_TABLE::executeSQL($sql);




            /*
              DELETE FROM NO_LIQUIDA_NOMINA tab0 where tab0.id_periodo = $periodo
              $whereFuncionarioNumDoc
              $whereFuncionarioTipoDoc
             */
            // Borrar no_liquida_nomina el periodo de retroactivo para cada periodo de ajuste - 20130604
            $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 and per.id_tipo_periodo != 2 )
    $whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
)                    
EOD;
            //ejecuta y obtiene el resultado del sql
            CN_TABLE::executeSQL($sql);

            /*
             * OJO: ID quemado
             * tag para buscar las vacaciones - ajuste vacaciones de periodos anteriores 
             * solo para el primer periodo de retroactivo - 20140303
             */
            if ($tag_rn == 1) {
                $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 per.id_tipo_periodo != 5
    --and tab0.id_concep_nomina in (7,27)
    $whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
)                    
EOD;
                //ejecuta y obtiene el resultado del sql
                CN_TABLE::executeSQL($sql);

                /*
                 * Borrar los registros del rango de periodo - 20150609
                 * Borrar no_liquida_nomina el periodo de retroactivo para cada periodo de ajuste-and per.id_tipo_periodo != 2 - 20210923::LAVILA
                 */
                $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 ( per.id_tipo_periodo != 5 )
    $whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
)                       
EOD;
                //ejecuta y obtiene el resultado del sql
                CN_TABLE::executeSQL($sql);
            }

            /**
             * Borrar no_liquida_nomina el periodo de retroactivo para cada periodo de ajuste - 20130604
             * Nomina Adicional - 20140304
             */
            $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 (select id_tipo_periodo from no_periodo where id_periodo = tab0.id_periodo_ajuste) = 2
    $whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
)                    
EOD;
            //ejecuta y obtiene el resultado del sql
            CN_TABLE::executeSQL($sql);

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

//MemcacheHandler::getInstance()->set($progress_key, 100);
//exit();
            /*
             * Liquida el periodo nuevo de retroactivo
             */
            $sql = <<<EOD
select tab0.*
from no_periodo tab0 
where tab0.id_tipo_periodo = 1 
and tab0.id_periodo>=$id_periodo_ini  and tab0.id_periodo<=$id_periodo_fin
order by tab0.fecha_fin 
EOD;

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

            $this->conn->commit();

            /*
             * 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] 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) {


                $id_periodo_ajuste = $resul['id_periodo'];

                //llamar para cada periodo y liquidar
                $this->liquidarRetroactivo($id_periodo, $id_periodo_ajuste, $progress_key, $record_consulta, $arrayConstantes, $whereFuncionarioNumDoc, $whereFuncionarioTipoDoc, $tag_rn);
//MemcacheHandler::getInstance()->set($progress_key, 100);
//exit();
                // 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, 10 + $por);
                }

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

                $i++;
//                break;
            }


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

            /*
             * Abrir conexion transaccion
             */
            $this->conn->beginTransaction();


            //Traer las diferencias de liquida nomina para rango de periodos
            /*
             * Se unen los registros de vacaciones para periodos anteriores . para el primer registro de periodo - 20140303
             * Se quita de la union de las vac la parte de ajuste y reintegro, por caso del 2013 y 2014 para el SGC, para 2015 no aplica.
             * then round((nvl(tab1.valor_liquidado,0)+nvl(tab5.valor_ajuste,0)-nvl(tab6.valor_rein,0))/tab1.num_dias*tab0.NUM_DIAS) - 20150616
             * Valor nuevo valor_ajuste_iss, Solo para retro de mensual y si es de nomina adicional, y tuvo vacaiones en la adicional, resta salud/pension - 2018028
             * Se cambia metodo por LISTAGG casos CEV - 20190705
             * Se deja min igual que la union de inico, para que coincida y no de repetido,-min(tab0.FECHA_DESDE) as FECHA_DESDE, 
             * Tambien se adicionan distinct, para evitar filas repetidas - 20210924::LAVILA
             * Validdivision en 0 (tab1.num_dias*tab0.NUM_DIAS) != 0, caso en que liquidaron dias 0 y valor 0, por ajustes negativos  - 20220405::LAVILA
             */
            $sql = <<<EOD
select distinct 
tab1.id_liq, 
tab1.ID_TIPO_DOC,
tab1.NUM_DOC,
tab1.ID_CONCEP_NOMINA,
$periodo AS ID_PERIODO,
tab1.DIFERENCIA AS VALOR_LIQUIDADO,
tab1.FECHA_DESDE,
tab1.FECHA_HASTA,
tab1.NUM_DIAS,
tab1.ID_PERIODO_AJUSTE,
tab1.PORCENTAJE,
nvl(tab2.valor_liquidado,0) as valor_ajuste_iss

FROM(

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

    FROM(

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

        from(

            select 
                --to_char(wm_concat(tab0.id_liquida_nomina)) as id_liq, 
                LISTAGG(tab0.id_liquida_nomina, ',') WITHIN GROUP (ORDER BY tab0.id_liquida_nomina) as id_liq, 
                tab0.ID_TIPO_DOC,tab0.NUM_DOC,tab0.ID_CONCEP_NOMINA,
                min(tab0.FECHA_DESDE) as FECHA_DESDE,
                max(tab0.FECHA_HASTA) as FECHA_HASTA,
                sum(tab0.NUM_DIAS) AS NUM_DIAS,
                max(tab0.PORCENTAJE) AS PORCENTAJE,
                tab0.ID_PERIODO_AJUSTE,sum(nvl(tab0.VALOR_LIQUIDADO,0)) AS VALOR,
                (select max(no_concep_nomina.id_concep_ajuste) as id_concep_ajuste from no_concep_nomina where tab0.id_concep_nomina = no_concep_nomina.id_concep_nomina) as id_concep_ajuste,
                (select max(no_concep_nomina.id_concep_rein) as id_concep_ajuste from no_concep_nomina where tab0.id_concep_nomina = no_concep_nomina.id_concep_nomina) as id_concep_rein

            from no_liquida_nomina tab0

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

            group by tab0.ID_TIPO_DOC,tab0.NUM_DOC,tab0.ID_CONCEP_NOMINA,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   

    UNION                    
 
         select tab0.*,
           case when (select no_param_concep.id_concep_vacac from no_param_concep where no_param_concep.id_param_concep = 1) = tab0.ID_CONCEP_NOMINA and (tab1.num_dias*tab0.NUM_DIAS) != 0 
           then round((nvl(tab1.valor_liquidado,0))/tab1.num_dias*tab0.NUM_DIAS)  
           else tab1.valor_liquidado -- + tab1.val_ajuste
           end AS VALOR_LIQUIDADO

        from(

            select 
                --to_char(wm_concat(tab0.id_liquida_nomina)) as id_liq, 
                LISTAGG(tab0.id_liquida_nomina, ',') WITHIN GROUP (ORDER BY tab0.id_liquida_nomina) as id_liq,
                tab0.ID_TIPO_DOC,tab0.NUM_DOC,tab0.ID_CONCEP_NOMINA,
                min(tab0.FECHA_DESDE) as FECHA_DESDE,
                max(tab0.FECHA_HASTA) as FECHA_HASTA,
                sum(tab0.NUM_DIAS) AS NUM_DIAS,
                max(tab0.PORCENTAJE) AS PORCENTAJE,
                tab0.ID_PERIODO_AJUSTE,sum(nvl(tab0.VALOR_LIQUIDADO,0)) AS VALOR,
                (select max(no_concep_nomina.id_concep_ajuste) as id_concep_ajuste from no_concep_nomina where tab0.id_concep_nomina = no_concep_nomina.id_concep_nomina) as id_concep_ajuste,
                (select max(no_concep_nomina.id_concep_rein) as id_concep_ajuste from no_concep_nomina where tab0.id_concep_nomina = no_concep_nomina.id_concep_nomina) as id_concep_rein

            from no_liquida_nomina tab0

            where tab0.id_periodo = $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,
              sum(nvl(tab1.num_dias,0)) as num_dias/*,
              
              nvl((
                    select 
                    --tab1.ID_TIPO_DOC,tab1.NUM_DOC,tab1.ID_CONCEP_NOMINA,tab1.ID_PERIODO,
                    sum(nvl(tab2.VALOR_LIQUIDADO,0)) AS VALOR_LIQUIDADO
                    from no_liquida_nomina tab2
                     where  tab2.num_doc = tab1.num_doc
                     and tab2.id_periodo  in (28,499)
                     and tab2.id_concep_nomina =  (select max(no_concep_nomina.id_concep_ajuste) as id_concep_ajuste from no_concep_nomina where tab1.id_concep_nomina = no_concep_nomina.id_concep_nomina)
                    group by tab2.id_tipo_doc,tab2.num_doc,tab2.id_concep_nomina 
              ),0) as val_ajuste*/
              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


         left join  (
              select 
                tab2.ID_TIPO_DOC,tab2.NUM_DOC,tab2.ID_CONCEP_NOMINA,
                --tab1.ID_PERIODO,
                sum(nvl(tab2.VALOR_LIQUIDADO,0)) AS valor_ajuste
                from no_liquida_nomina tab2
                where tab2.id_periodo  in (28,499)    
                group by tab2.id_tipo_doc,tab2.num_doc,tab2.id_concep_nomina 
          )tab5
          ON tab5.id_tipo_doc = tab0.id_tipo_doc and tab5.num_doc = tab0.num_doc 
              and tab5.id_concep_nomina = tab0.id_concep_ajuste


         left join  (
              select 
                tab2.ID_TIPO_DOC,tab2.NUM_DOC,tab2.ID_CONCEP_NOMINA,
                --tab1.ID_PERIODO,
                sum(nvl(tab2.VALOR_LIQUIDADO,0)) AS valor_rein
                from no_liquida_nomina tab2
                where tab2.id_periodo  in (28,499)    
                group by tab2.id_tipo_doc,tab2.num_doc,tab2.id_concep_nomina 
          )tab6
          ON tab6.id_tipo_doc = tab0.id_tipo_doc and tab6.num_doc = tab0.num_doc 
              and tab6.id_concep_nomina = tab0.id_concep_rein
                    

            where tab0.num_doc IS NOT NULL
            --AND tab0.ID_CONCEP_NOMINA = 7
            and $tag_rn = 1 
            $whereFuncionarioNumDoc
            $whereFuncionarioTipoDoc    
                    
        )           
)tab1

/* solo para retro de mensual y si es de nomina adicional, y tuvo vacaiones en la adicional, resta salud/pension - 2018028 */
left join(

    select 
    tab0.id_tipo_doc,
    tab0.num_doc,
    tab0.id_concep_nomina,
    sum(tab0.valor_liquidado) as valor_liquidado
    
    from no_liquida_nomina tab0
    
    join no_periodo per
    on per.id_periodo = tab0.id_periodo
    
    join no_concep_nomina concep
    on concep.id_concep_nomina = tab0.id_concep_nomina
    
    where
    per.id_anhos = (select id_anhos from no_periodo where id_periodo = $id_periodo_ajuste)
    and per.id_meses = (select id_meses from no_periodo where id_periodo = $id_periodo_ajuste)
    and 1 = (select id_tipo_periodo from no_periodo where id_periodo = $id_periodo_ajuste)
    and per.id_tipo_periodo in (2)
    and concep.id_tipo_concepto in (2)
    
    and (tab0.id_tipo_doc,tab0.num_doc) in (
          select distinct
          tab0.id_tipo_doc, tab0.num_doc
          from no_liquida_nomina tab0
              
          join no_periodo per
          on per.id_periodo = tab0.id_periodo
          
          where
          per.id_anhos = (select id_anhos from no_periodo where id_periodo = $id_periodo_ajuste)
          and per.id_meses = (select id_meses from no_periodo where id_periodo = $id_periodo_ajuste)
          and per.id_tipo_periodo in (2)
          and tab0.id_concep_nomina in (select no_param_concep.id_concep_vacac from no_param_concep where no_param_concep.id_param_concep = 1)
    )
    
    group by
    tab0.id_tipo_doc,
    tab0.num_doc,
    tab0.id_concep_nomina

)tab2
on
tab2.id_tipo_doc = tab1.id_tipo_doc
and tab2.num_doc = tab1.num_doc
and tab2.id_concep_nomina = tab1.id_concep_nomina

where
(select id_tipo_periodo from no_periodo where id_periodo = tab1.id_periodo_ajuste) not in (5) 
and tab1.DIFERENCIA is not null
                    
order by
tab1.NUM_DOC,
tab1.ID_CONCEP_NOMINA                
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);

            $this->logMessage("[Liquidación Retroactivo] Liquidar diferencias de mensual.");

            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_liq = $resul['id_liq'];
                $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'];
                $valor_ajuste_iss = $resul['valor_ajuste_iss'];
                $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'];
                }
                $porcentaje = 'null';
                if (!is_null($resul['porcentaje'])) {
                    $porcentaje = $resul['porcentaje'];
                }
                $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 = $periodo
    and tab0.id_liquida_nomina in ($id_liq)
EOD;
                //ejecuta y obtiene el resultado del sql
                CN_TABLE::executeSQL($sql);

                /*
                 * Se trae el id de concepto nomina si tiene id de ajuste
                 * Que solo tome el concepto de ajuste para los devengados - 20190611
                 */
                $sql = <<<EOD
select case 
when tab0.id_concep_ajuste is null then tab0.id_concep_nomina 
when tab0.id_concep_ajuste is not null and tab0.id_tipo_concepto != 1 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
                $this->logMessage("[Liquidación Retroactivo] Insertar valor::" . $valor_ajuste_iss);
                $valor = $valor - $valor_ajuste_iss;
                $this->logMessage("[Liquidación Retroactivo] Insertar valor::" . $valor);
                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,PORCENTAJE) 
             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, $porcentaje)
EOD;
                    //ejecuta y obtiene el resultado del sql
                    CN_TABLE::executeSQL($sql);
                }
            }
            MemcacheHandler::getInstance()->set($progress_key, 99);

            //COMMIT DE TODAS LAS TRANSACCIONES
            $this->logMessage("[Liquidación Retroactivo] COMMIT DE TODAS LAS TRANSACCIONES - Liquidar diferencias de mensual.");
            $this->conn->commit();



            /**
             * **************************************************************
             * Nomina Adicional - 20140304
             * ************************************************************** 
             */
            $this->logMessage("[Liquidación Retroactivo] Nomina Adicional.");
            /*
             * Abrir conexion transaccion
             */
            $this->conn->beginTransaction();

            $id_periodo_ajuste = $id_periodo_aju_men; //periodo de ajuste mensual periodo_ini
            //TRAIGO LOS PERIODOS QUE SE AFECTAN CON LOS PERIODOS SELECCIONADOS - nomina adicional

            $sql = <<<EOD
select tab0.*
from no_periodo tab0 
where tab0.id_tipo_periodo in (2,3)
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_ajuste) 
order by tab0.fecha_fin 
EOD;

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

            foreach ($results as $resul) {

                $id_periodo_ajuste = $resul['id_periodo']; //periodo de ajuste - mensual

                /*
                 * Inserta en NO_CONCEPTO_PERIODO los conceptos para cada periodo en el periodo de retroactivo
                 */
                $sql = <<<EOD
INSERT INTO NO_CONCEPTO_PERIODO 
(ID_ANHOS,ID_MESES,PERIODO,ID_TIPO_DOC,NUM_DOC,ID_CONCEP_NOMINA,FECHA_DESDE,
    FECHA_HASTA,VALOR,PORCENTAJE,NUM_DIAS,ID_PERIODO_AJUSTE)

select 
    
tab0.ID_ANHOS,
tab0.ID_MESES,
tab0.PERIODO,
tab0.ID_TIPO_DOC,
tab0.NUM_DOC,
tab0.ID_CONCEP_NOMINA,
tab0.FECHA_DESDE,
tab0.FECHA_HASTA,
tab0.VALOR,
tab0.PORCENTAJE,
tab0.NUM_DIAS,
tab0.ID_PERIODO_AJUSTE

from(

      select 
      tab0.id_concepto_periodo, tab2.id_meses ID_MESES,tab2.id_anhos ID_ANHOS,
      tab2.id_periodo PERIODO,tab0.id_tipo_doc ID_TIPO_DOC,tab0.num_doc,tab0.id_concep_nomina,
      tab2.fecha_ini AS FECHA_DESDE, tab2.fecha_fin AS FECHA_HASTA,
      tab0.porcentaje AS PORCENTAJE, tab0.num_dias AS NUM_DIAS, tab0.periodo AS ID_PERIODO_AJUSTE,
      
      case when tab0.id_concep_nomina = 1 or tab0.id_concep_nomina = 401 then (
          select tab2.asignacion_basica
                from no_estado_func_v tab1
          left join no_dp_v tab2 ON tab2.id_dp = tab1.id_dp
          where tab1.rn=1 and tab1.num_doc = tab0.num_doc 
          --and tab1.actual = 1 
          and tab1.periodo = $id_periodo_ajuste
      )
      else
      
      tab0.valor end
      
      AS VALOR,tab0.valor AS VALOR_ANTERIOR
      
      from no_concepto_periodo tab0
      left join no_concep_nomina tab1 ON tab1.id_concep_nomina = tab0.id_concep_nomina  
      left join no_periodo tab2 ON tab2.id_periodo = $periodo
      
      where 
      tab0.periodo = $id_periodo_ajuste 
      AND(tab1.id_tipo_concepto=1 or tab1.id_tipo_concepto=2 or tab1.id_tipo_concepto=3)

)tab0 
                        
                        
join no_estado_func tab3 ON tab3.id_tipo_doc = tab0.id_tipo_doc 
    and tab3.num_doc = tab0.num_doc and tab3.periodo = $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    
and tab0.ID_CONCEP_NOMINA not in (SELECT id_concep_rete FROM no_param_concep)
                        
ORDER BY tab0.NUM_DOC, tab0.ID_CONCEP_NOMINA, tab0.id_periodo_ajuste, tab0.id_concepto_periodo         
                    
EOD;

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

            /*
             * Liquida el periodo nuevo de retroactivo - nomina adicional
             */
            $sql = <<<EOD
select tab0.*
from no_periodo tab0 
where tab0.id_tipo_periodo in (2,3) 
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_ajuste) 
order by tab0.fecha_fin 
EOD;

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

            $this->conn->commit();

            /*
             * Recorre los registros de funcionario - concepto nomina
             * para ser liquidados
             */
            $this->logMessage("[Liquidación Retroactivo Adicional] 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));

            $this->logMessage("[Liquidación Retroactivo] Liquidar diferencias de nomina adicional.");

            $si_nom_adic = false;

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

                $id_periodo_ajuste = $resul['id_periodo'];
                $si_nom_adic = true;
                $this->logMessage("[Liquidación Retroactivo] INICIO - For de liquidar por cada periodo entre el rango. Periodo::" . $id_periodo_ajuste);

                //llamar para cada periodo y liquidar
                $this->liquidarRetroactivo($periodo, $id_periodo_ajuste, $progress_key, $record_consulta, $arrayConstantes, $whereFuncionarioNumDoc, $whereFuncionarioTipoDoc, 0);

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

                /*
                 * Validar si hay nomina adicional en el mes - 20140410
                 */
                if ($si_nom_adic) {

                    /*
                     * Abrir conexion transaccion
                     */
                    $this->conn->beginTransaction();


                    //Traer las diferencias de liquida nomina para rango de periodos
                    //Se unen los registros de vacaciones para periodos anteriores . para el primer registro de periodo - 20140303
                    //Se coloca min y max a fecha, para que no se agrupe por estas - 20210928::LAVILA
                    $sql = <<<EOD

select ID_TIPO_DOC,NUM_DOC,ID_CONCEP_NOMINA,$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,
                max(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 = $periodo  and tab0.id_periodo_ajuste = $id_periodo_ajuste 
    
                group by tab0.ID_TIPO_DOC,tab0.NUM_DOC,tab0.ID_CONCEP_NOMINA,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);

                    $this->logMessage("[Liquidación Retroactivo] INI - Liquidar diferencias de nomina adicional.");

                    foreach ($results as $resul) {

                        $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 = $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);
                        }
                    }

                    //COMMIT DE TODAS LAS TRANSACCIONES
                    $this->logMessage("[Liquidación Retroactivo] COMMIT DE TODAS LAS TRANSACCIONES - Liquidar diferecias de nomina adicional.");
                    $this->conn->commit();
                }
                $this->logMessage("[Liquidación Retroactivo] FIN - For de liquidar por cada periodo entre el rango. Periodo::" . $id_periodo_ajuste);
            }
            $this->logMessage("[Liquidación Retroactivo] Fin - Liquidar diferecias de nomina adicional.");

            /*
             * Final mencache
             */
            MemcacheHandler::getInstance()->set($progress_key, 100);



            /**
             * Sumar para vacaciones del anho anterior que toman dias del periodo de retroactivo, 
             * para las deducciones de ley el concepto 1007 y 1027, de los dias que corresponden. - 20150611 
             * Se toma lo liquidado del 1007 y 1027 del mes y se suma al concepto segun su porcentaje de calculo
             */
            /*
             * Abrir conexion transaccion
             */
            $this->conn->beginTransaction();

            /*
             * Personas y periodos de las vac
             * Se cambia metodo por LISTAGG casos CEV - 20190705
             */
            $sql = <<<EOD
  select 
        count(nov.num_doc) as cant,
        --to_char(wm_concat(DISTINCT nov.num_doc)) as num_docs,
        --to_char(wm_concat(DISTINCT nov.id_periodo)) as id_periodos
        LISTAGG(nov.num_doc, ',') WITHIN GROUP (ORDER BY nov.num_doc) as num_docs,
        LISTAGG(nov.id_periodo, ',') WITHIN GROUP (ORDER BY nov.id_periodo) as id_periodos            

        from no_novedad_vac nov

        join no_periodo_v perv
        on perv.id_periodo = nov.id_periodo

        join no_concep_vac convac
        on nov.id_tipo_nov_vac = convac.id_tipo_nov_vac

        where nov.fecha_fin >= (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ini)
        /*between (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ini) 
          and (select per.fecha_fin from no_periodo per where per.id_periodo = $id_periodo_ini)*/
        --and nov.fecha_ini < (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ini) 
                        
        and perv.id_anhos != (select per.id_anhos from no_periodo per where per.id_periodo = $id_periodo_ini)
        and perv.id_meses != (select per.id_meses from no_periodo per where per.id_periodo = $id_periodo_ini)
        and perv.fecha_fin < (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ini) 
                    
        AND convac.id_concep_nomina = (select no_param_concep.id_concep_vacac from no_param_concep where no_param_concep.id_param_concep = 1)  
EOD;
            //Ejecutar SQL
            $recordss = CN_TABLE::executeSQL($sql);

            /**
             * Incidente #29315, Para SGC no toma ajuste de aportes por el periodo de vacaciones del año anterior - 20220411::LAVILA
             */
            //(SGC-1, ANM-2, SGR-3, CYC-4, COL-5, INCI-6, LOCAL-7)
            if ($entidadCliente == 1) {
                $tag_rn = 0;
            }

            //validar que hay num_doc por la cant
            if (count($recordss) > 0 && isset($recordss[0]['cant']) && $recordss[0]['cant'] > 0 && $tag_rn == 1) {

                $num_docs = $recordss[0]['num_docs'];
                $id_periodos = $recordss[0]['id_periodos'];

                //Recorres personas que aplican vac y los conceptos de deducidos de ley, segun tabla fondo_concepto
                //Sql
                $sql = <<<EOD
select 
tab0.* ,
nvl((select sum(valor_liquidado) from no_liquida_nomina
where id_periodo = $id_periodo
and id_periodo_ajuste in (  $id_periodos )
and id_concep_nomina in ( (select id_concep_vacac from no_param_concep where id_param_concep = 1), ( select nvl(id_concep_ajuste,id_concep_nomina) from no_concep_nomina where id_concep_nomina =(select id_concep_vacac from no_param_concep where id_param_concep = 1)) )
and num_doc in ( tab0.num_doc )) ,0) as valor
                        
from no_liquida_nomina tab0
where
tab0.id_periodo = $id_periodo
and tab0.id_periodo_ajuste in (  $periodos )

and tab0.id_concep_nomina in (select distinct no_fondo_concepto.id_concep_nomina from no_fondo_concepto) 
and nvl(tab0.porcentaje,0) > 0

and tab0.num_doc in ( $num_docs )
                    
$whereFuncionarioNumDoc
$whereFuncionarioTipoDoc 

order by
tab0.num_doc,
tab0.id_concep_nomina 
EOD;
                //Ejecutar SQL
                $records = CN_TABLE::executeSQL($sql);

                //Para cada uno toma valores de 1007 y 1027, y calcula el porcentaje que corresponda
                foreach ($records as $value) {

                    $id_liquida_nomina = $value['id_liquida_nomina'];
                    $valor = $value['valor'] * 1;
                    $porcentaje = $value['porcentaje'] * 1;
                    $this->logMessage("[Liquidación Retroactivo] valor::" . $valor . " - porcentaje::" . $porcentaje);

                    $valor_liquidado = (($valor * $porcentaje) / 100);
                    //$valor_liquidado = round($valor_liquidado);
                    //Redondeo al 100 hacia arriba - 20170615
                    $valor_liquidado = CN_TABLE::ceiling($valor_liquidado, 100);
                    $this->logMessage("[Liquidación Retroactivo] valor_liquidado::" . $valor_liquidado);

                    //Actualiza el valor del concepto
                    $sql = <<<EOD
update no_liquida_nomina set valor_liquidado = valor_liquidado + nvl( $valor_liquidado ,0) 
where id_liquida_nomina = $id_liquida_nomina                   
EOD;
                    //ejecuta y obtiene el resultado del sql
                    CN_TABLE::executeSQL($sql);
                }
            }
            $this->logMessage("[Liquidación Retroactivo] Sumar para vacaciones del anho anterior que toman dias del periodo de retroactivo.");
            $this->conn->commit();

            /**
             * Se coloca que para los ajustes de aplicar_liq_concep - 20220510::LAVILA
             * Ajuste para periodos de otro año anterior - 20230901::LAVILA
             */
            $id_periodo_ajuste = $id_periodo_aju_men; //periodo de ajuste mensual periodo_ini

            $sql = <<<EOD
select  
nvl(wm_concat(distinct liq.id_periodo_ajuste),0) as periodos_vac
from no_liquida_nomina liq
    left join no_periodo per on liq.id_periodo_ajuste = per.id_periodo
    where liq.id_periodo = $id_periodo
    and per.id_anhos in ( select id_anhos - 1 from no_periodo where id_periodo = $id_periodo )
    and 1 = ( select id_meses from no_periodo where id_periodo = $id_periodo_ajuste )
EOD;
            $results = CN_TABLE::executeSQL($sql);
            $periodos_vac = $results[0]['periodos_vac'];

            /*
             * Abrir conexion transaccion
             */
            $this->conn->beginTransaction();
            //Sql
            $sql = <<<EOD
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,
nvl(tab0.valor_base,0) as valor_base,
tab0.id_periodo_ajuste    
                    
from no_ajuste_nomina tab0
join no_periodo per
on per.id_periodo = tab0.id_periodo 

WHERE 
tab0.aplicar_liq_concep = 1                     
and tab0.id_periodo = $id_periodo 
and tab0.id_periodo_ajuste in ( $id_periodo_ajuste , $periodos_vac )
$whereFuncionarioNumDoc    
EOD;

            //Ejecutar SQL
            $record_ajuste_liq = CN_TABLE::executeSQL($sql);

            foreach ($record_ajuste_liq as $value_liq) {

                $id_tipo_doc = $value_liq['id_tipo_doc'];
                $num_doc = $value_liq['num_doc'];
                $id_concep_nomina = $value_liq['id_concep_nomina'];
                $id_periodo = $value_liq['id_periodo'];
                $valor_ajuste = $value_liq['valor_ajuste'];
                $num_dias = $value_liq['num_dias'];
                $valor_base = $value_liq['valor_base'];
                $id_periodo_ajuste = $value_liq['id_periodo_ajuste'];

                //Actualizar cada funcionario-concepto de la liquidacion                
                $sql = <<<EOD
update no_liquida_nomina set valor_liquidado = valor_liquidado + $valor_ajuste, 
    num_dias = num_dias + $num_dias, 
    valor_base = valor_base + ($valor_base) 
where 
num_doc = '$num_doc'
and id_concep_nomina = $id_concep_nomina 
and id_periodo = $id_periodo 
and id_tipo_doc = $id_tipo_doc 
and id_periodo_ajuste = $id_periodo_ajuste 
EOD;
                //Ejecutar SQL
                $this->conn->execute($sql);
            }
            $this->logMessage("[Liquidación Retroactivo] Ajuste nuevo de APLICAR_LIQ_CONCEP.");
            $this->conn->commit();

            $records = array();

            $this->totalRows = 0;
            $this->startRow = 0;
            $this->endRow = 0;
            $this->list_data = $records;
            $this->logMessage("[Liquidación Retroactivo] 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] Ocurrio un error: " . $e->getMessage();
            $this->list_data = array();
            $this->logMessage("[Liquidación Retroactivo] ERROR!!!");
            $this->logMessage($e->getMessage());
        }
    }

    /**
     * Calcular FSP aporte funcionario
     * @param type $valor_base
     * @param type $salario_minimo
     * @return int
     */
    private function valor_base_fsp($valor_base, $salario_minimo, $valor_base_vac = 0, $wdiasv = 0, $dias_liq, $num_doc, $id_periodo_ajuste) {

        $this->logMessage("[Liquidación] valor_base_fsp:: valor_base: " . $valor_base . " - valor_base_vac: " . $valor_base_vac);
        $this->logMessage("[Liquidación] valor_base_fsp:: wdiasv: " . $wdiasv . " - dias_liq: " . $dias_liq);


        /*
         * WBASE=   BASE TOTAL que ya estamos hayando
         * WVRBASE=(WBASE/(WDIAST+WDIASV))*30
         * Sobre WVRBASE  verifica si debe calcular FSP y sobre ella misma ubicar el porcentaje 
         * Si aplica y tiene el porcentaje,  aplica el porcentaje sobre WBASE
         * 20131216
         */
        $valor = 0;
        $valorfps1 = 0;
        $valorfps2 = 0;
        $porcentaje = 0;
        $valor_bonif = 0;
        $valor_bonifs = 0;


        /**
         * Para las personas que tienen bonificacion por servicios se toma este valor proporcional a los dias laborados - 20140605
         */
        //Sql
        $sql = <<<EOD
select nvl(sum(valor_liquidado),0) as valor from no_liquida_nomina 
where num_doc = $num_doc and id_tipo_doc = 1 
and id_concep_nomina = (select no_param_concep.id_concep_bonif from no_param_concep where no_param_concep.id_param_concep = 1) 
and id_periodo_ajuste = $id_periodo_ajuste            
EOD;
        //Ejecutar SQL
        $records = CN_TABLE::executeSQL($sql);

        /*
         * Valida si posee el concepto
         */
        if (count($records) > 0 && $dias_liq > 0) {
            $valor_bonifs = $records[0]['valor']; //bonificacion completa
            $valor_bonif = (($valor_bonifs * $dias_liq) / 30); //bonificacion por dias laborales
        }
        $this->logMessage("[Liquidación] Valida si la persona - valor_bonif :: " . $valor_bonif);


        /*
         * Operaciones
         * Se quita la resta (- $valor_bonifs), toma el valor proporcional de los dias trabajados - 20150203 NO VA, porque el valor esta en la base por la agrupacion
         * Se separa el valor bonif del redondeo a 30 dias laborales, ya que en el proceso anterior ya se realiza su calculo para los 30 dias - 20150218
         */
        //$wvalor_base = (($valor_base + $valor_bonif) / ($dias_liq + $wdiasv)) * 30;
        //$wvalor_base = (($valor_base - $valor_bonifs + $valor_bonif) / ($dias_liq + $wdiasv)) * 30;
        $wvalor_base = (($valor_base - $valor_bonifs) / ($dias_liq + $wdiasv) * 30 ) + ($valor_bonif);



        /**
         * Valida si la persona ingreso en el mes o se retira para tomar los dias en cuenta - 20140307
         */
        $this->logMessage("[Liquidación] Valida si la persona - wvalor_base :: " . $wvalor_base);
        //Sql
        $sql = <<<EOD
select 
nom.* 
from no_nombramiento_v nom
where 
nom.id_tipo_doc = 1
and nom.num_doc = $num_doc
and (
nom.fecha_ingreso between (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) and (select per.fecha_fin from no_periodo per where per.id_periodo = $id_periodo_ajuste)
or 
nom.fecha_termina between (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) and (select per.fecha_fin from no_periodo per where per.id_periodo = $id_periodo_ajuste)
)                
EOD;
        //Ejecutar SQL
        $records = CN_TABLE::executeSQL($sql);

        /*
         * Valida si posee formula el concepto
         */
        if (count($records) > 0) {
            $wvalor_base = $valor_base + $valor_base_vac + $valor_bonif;
            $this->logMessage("[Liquidación] Valida si posee formula el concepto - wvalor_base :: " . $wvalor_base);
        }


        //Cambio de verificacion del valor base - 20131216
        if (($wvalor_base) > ($salario_minimo * 4) && ($wvalor_base) <= ($salario_minimo * 16)) {
            $porcentaje = 1;
        } elseif (($wvalor_base) > ($salario_minimo * 16) && ($wvalor_base) <= ($salario_minimo * 17)) {
            $porcentaje = 1.2;
        } elseif (($wvalor_base) > ($salario_minimo * 17) && ($wvalor_base) <= ($salario_minimo * 18)) {
            $porcentaje = 1.4;
        } elseif (($wvalor_base) > ($salario_minimo * 18) && ($wvalor_base) <= ($salario_minimo * 19)) {
            $porcentaje = 1.6;
        } elseif (($wvalor_base) > ($salario_minimo * 19) && ($wvalor_base) <= ($salario_minimo * 20)) {
            $porcentaje = 1.8;
        } elseif (($wvalor_base) > ($salario_minimo * 20)) {
            $porcentaje = 2;
        }

        /* INCI - 20140122
         * Patricia Montoya Falla, C.C. 35.462.698,
          Esperanza Verdugo, C.C.  46.662.659
          Yanerys Irina de la Hoz, C.C.  57.290.110
          Vladimir Yanken Cifuentes, C.C. 79.526.123
          Gustavo Pulido Casas, C.C. 93.288.443
         * 39773464
         */
        if ($num_doc == '35462698' || $num_doc == '46662659' || $num_doc == '57290110' || $num_doc == '79526123' || $num_doc == '93288443' || $num_doc == '51788859') {
            if (($valor_base + $valor_base_vac) > ($salario_minimo * 4) && ($valor_base + $valor_base_vac) <= ($salario_minimo * 16)) {
                $porcentaje = 1;
            } elseif (($valor_base + $valor_base_vac) > ($salario_minimo * 16) && ($valor_base + $valor_base_vac) <= ($salario_minimo * 17)) {
                $porcentaje = 1.2;
            } elseif (($valor_base + $valor_base_vac) > ($salario_minimo * 17) && ($valor_base + $valor_base_vac) <= ($salario_minimo * 18)) {
                $porcentaje = 1.4;
            } elseif (($valor_base + $valor_base_vac) > ($salario_minimo * 18) && ($valor_base + $valor_base_vac) <= ($salario_minimo * 19)) {
                $porcentaje = 1.6;
            } elseif (($valor_base + $valor_base_vac) > ($salario_minimo * 19) && ($valor_base + $valor_base_vac) <= ($salario_minimo * 20)) {
                $porcentaje = 1.8;
            } elseif (($valor_base + $valor_base_vac) > ($salario_minimo * 20)) {
                $porcentaje = 2;
            }
        }
        //num_doc in (13507148, 51653492 ,79250331 ,52779827 ,20404209)
        if ($num_doc == '51653492' || $num_doc == '79250331' || $num_doc == '6193881') {
            $porcentaje = 0;
        }

        /**
         * Se redondea valor al sumar al final y no $valorfps1 / $valorfps2, por separado  - 20140616
         */
        $this->logMessage("[Liquidación] valor_base_fsp:: valor_base: " . $valor_base);
//        $valorfps1 = round($valor_base * 0.5 / 100, -2);
//        $valorfps2 = round($valor_base * ($porcentaje - 0.5) / 100, -2);
        $valorfps1 = $valor_base * 0.5 / 100;
        $valorfps2 = $valor_base * ($porcentaje - 0.5) / 100;
        $this->logMessage("[Liquidación] valor_base_fsp:: valorfps1: " . $valorfps1 . " - valorfps2: " . $valorfps2);

        //$valor = $valorfps1 + $valorfps2;
        //$valor = CN_TABLE::redondeoValor($valorfps1, -2) + CN_TABLE::redondeoValor($valorfps2, -2);
        $valor = CN_TABLE::ceiling($valorfps1, 100) + CN_TABLE::ceiling($valorfps2, 100);

        //Valida que si porcentaje 0, el valor de aporte es 0 - 20170307
        if ($porcentaje == 0) {
            $valor = 0;
        }

        $array_fsp = array(
            'valor_fsp' => $valor,
            'porcentaje_fsp' => $porcentaje
        );

        return $array_fsp;
    }

    /**
     * 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
     */
    private function liquidar($id_periodo, $num_doc, $id_tipo_doc, $id_concep_nomina, $record_liq, $arrayConstantes, $record_consulta, $id_periodo_ajuste) {
        $this->logMessage("[Liquidación Retroactivo] Liquidar: periodo " . $id_periodo .
                " - funcionario " . $num_doc . " - concepto nomina " . $id_concep_nomina);

        /**
         * Varibles
         */
        $arrayParametros = array();
        /*
         * Variable para optimizar consultas de formulas en las liquidaciones - 20140117
         */
        $vals_calc = array();
        $valor_liquidado = 0;
        $fecha_desde = $record_liq['fecha_desde'];
        $fecha_hasta = $record_liq['fecha_hasta'];
        $num_dias = $record_liq['num_dias'];
        $id_periodo_ajuste_conper = $record_liq['id_periodo_ajuste'];
        $porc_incre_salarial = $record_liq['porc_incre_salarial'];

        //Concepto Nomina 1009 Vacaciones
        if ($id_concep_nomina == 9) {
            $record_liq['vig_ini'] = $record_liq['id_anhos'];
            $record_liq['per_ini'] = 1;
            $record_liq['vig_fin'] = $record_liq['id_anhos'];
            $record_liq['per_fin'] = $record_liq['id_meses'];
        }

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

        /*
         * Cargar fórmulas por concepto
         * Se modifico formula Para aporte en salud, pensión y FSP  existe un tope máximo de aporte de 25 SMLV
         * se toma del id_concep_nomina asociado al descuento - 20130814
         * Se agrega tag_fondo y aplica_ibc_ant_vac para conocer si el id es de fondo - 20200710::LAVILA*SE DEJA COMENTADO; YA QUE NO APLICO CORRECTAMENTE
         */
//        $tag_fondo = 0;
//        $aplica_ibc_ant_vac = 0;
//        $valor_liquidado_fondo = 0;
//        $id_meses_tag = 0;
//        $dias_vac_ant_ene = 0;
        //Sql
        $sql = <<<EOD
select distinct 
(select id_meses from no_periodo where id_periodo = $id_periodo_ajuste ) as id_meses_tag,
(select count(*) from no_fondo_concepto where id_concep_nomina = $id_concep_nomina) as tag_fondo,
(select aplica_ibc_ant_vac from no_param_gen where id_param_gen = 1) as tag_aplica_ibc_ant_vac,
formu.* 
from no_formula formu
                
   WHERE id_concep_nomina =   (    
   
  select distinct 
  nvl( id_concep_nomina_ss, ID_CONCEP_NOMINA) as ID_CONCEP_NOMINA 
  from
  (
  
      select 
      formula.ID_FORMULA,
      formula.ID_CONCEP_NOMINA,
      formula.FORMULA,
      formula.NOMBRE,
      formula.COD_TIPO,
      foncon.id_descuento_ss,
      des.id_concep_nomina as id_concep_nomina_ss
      from no_formula formula
      left join no_fondo_concepto foncon
      on formula.id_concep_nomina = foncon.id_concep_nomina
      left join no_descuento_ss des
      on foncon.id_descuento_ss = des.id_descuento_ss
      where formula.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] Entro a calcular Formula.");
            /*
              $tag_fondo = $records[0]['tag_fondo'];
              $aplica_ibc_ant_vac = $records[0]['tag_aplica_ibc_ant_vac'];
              $id_meses_tag = $records[0]['id_meses_tag'];

              if ($tag_fondo != 0 && $aplica_ibc_ant_vac == 1) {
              $this->logMessage("[Liquidación] IBC del mes anterior de las vacaciones.");

              $sql_mes_tag = <<<EOD
              and novvac.id_periodo in ( $id_periodo_ajuste )
              EOD;
              if ($id_meses_tag == 1) {
              $sql_mes_tag = <<<EOD
              and novvac.fecha_ini < (select fecha_ini from no_periodo where id_periodo in ( $id_periodo_ajuste ))
              and novvac.fecha_fin
              between (select fecha_ini from no_periodo where id_periodo in ( $id_periodo_ajuste ))
              and (select fecha_fin from no_periodo where id_periodo in ( $id_periodo_ajuste ))
              EOD;
              //Vacaciones solo dias enero, que inician antes de enero de la vigencia - 20210923::LAVILA
              $sql = <<<EOD
              select
              nvl(sum(dias_rango_mes(fecha_ini,fecha_fin,(select id_meses from no_periodo where id_periodo in ( $id_periodo_ajuste )))),0) as dias_vac_ant_ene

              from no_novedad_vac novvac
              left join no_tipo_nov_vac tipnov on tipnov.id_tipo_nov_vac = novvac.id_tipo_nov_vac
              where tipnov.tiempo_liqui = 1 and tipnov.operador = 1
              and novvac.num_doc = '$num_doc'
              --and novvac.id_periodo in ( $id_periodo_ajuste )
              and novvac.fecha_ini < (select fecha_ini from no_periodo where id_periodo in ( $id_periodo_ajuste ))
              and novvac.fecha_fin between (select fecha_ini from no_periodo where id_periodo in ( $id_periodo_ajuste )) and (select fecha_fin from no_periodo where id_periodo in ( $id_periodo_ajuste ))
              EOD;
              $records_fondo_dias = CN_TABLE::executeSQL($sql);

              if (count($records_fondo_dias) > 0) {
              $dias_vac_ant_ene = $records_fondo_dias[0]['dias_vac_ant_ene'];
              }
              }

              //Sql - IBC del mes anterior de las vacaciones
              $sql = <<<EOD
              SELECT
              id_periodo,
              id_tipo_doc,
              num_doc,
              sum(valor_base) as valor_base
              FROM no_liquida_aporte
              where
              id_periodo = (

              (SELECT
              max(perd.id_periodo)
              FROM no_periodo perd where perd.id_tipo_periodo = 1 and perd.fecha_fin < ( select
              max(novvac.fecha_ini) as fecha_ini

              from no_novedad_vac novvac
              left join no_tipo_nov_vac tipnov on tipnov.id_tipo_nov_vac = novvac.id_tipo_nov_vac
              where tipnov.tiempo_liqui = 1 and tipnov.operador = 1
              and novvac.num_doc = '$num_doc'
              $sql_mes_tag
              group by novvac.id_tipo_doc, novvac.num_doc ) )

              )
              --and id_tipo_doc = 1
              and num_doc = '$num_doc'
              and id_clase_fondo = 2
              and tipo_planilla = 'A'

              group by
              id_periodo,
              id_tipo_doc,
              num_doc
              EOD;
              $records_fondo = CN_TABLE::executeSQL($sql);

              if (count($records_fondo) > 0) {
              $this->logMessage("[Liquidación] Calculo IBC del mes anterior de las vacaciones.");

              $valor_base_fondo = $records_fondo[0]['valor_base'];
              $valor_liquidado_fondo = $valor_base_fondo;

              $this->logMessage("[Liquidación] Calculo IBC del mes anterior valor_liquidado_fondo::" . $valor_liquidado_fondo);
              }
              }
             */
            foreach ($records as $value) {

                //se adiciona un nuevo campo de formula para completar la retencion que es muy grande el proceso - 20210415::LAVILA
                $formula = $value['formula'] . $value['formula_adic'];
                //Para calculo de prima servicios - 20190715
                //Se verifico que sea por formula y no $porc_incre_salarial - 20210909::LAVILA
                if ($id_concep_nomina == 16) {
                    //$formula = " (  ( 0 ) >=0 ? ( ({U16})/100 * $porc_incre_salarial )  + ({U16}) : -9999 ) ";
                }
                $this->logMessage("[Liquidación Retroactivo] Formula Inicial: " . $formula);

                //Se agrega tag_fondo para conocer si el id es de fondo - 20200710::LAVILA
//                if ($tag_fondo != 0 && $valor_liquidado_fondo != 0) {
//                    $formula = str_replace('{A39}', $valor_liquidado_fondo, $formula);
//                    $this->logMessage("[Liquidación] Calculo IBC del mes anterior Formula: " . $formula);
//                }
//                if ($aplica_ibc_ant_vac == 1 && $dias_vac_ant_ene != 0) {
//                    $formula = str_replace('$wdiasv', $dias_vac_ant_ene, $formula);
//                    $this->logMessage("[Liquidación] Calculo wdiasv de la Formula: " . $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] 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
                 */
                $formula = CN_TABLE::reemplazoConsulta($formula, $record_liq);
                $this->logMessage("[Liquidación Retroactivo] 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'
                         */
                        $this->logMessage("[Liquidación] vals_calc: " . $var);
                        if (!isset($vals_calc[$var])) {
                            $formula_agrup = $this->reemplazoAgrupacion(substr($var, 1));
                            $this->logMessage("[$var] [Liquidación Agrupación] Agrupacion: " . $formula_agrup);

                            // $formula = str_replace('{' . $var . '}', $agrup, $formula);
                            $params_agrup = $this->parametrosFormula($formula_agrup);
                            $res_agrup = $this->resultadoParametros($params_agrup, $record_liq, $record_consulta, $vals_calc, $id_concep_nomina);
                            $formula_agrup = $this->reemplazoParametros($formula_agrup, $res_agrup);

                            $formula_agrup = str_replace('{', ' ', $formula_agrup);
                            $formula_agrup = str_replace('}', ' ', $formula_agrup);
                            $result_agrup = CN_TABLE::aplicarEval($formula_agrup);

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

                            $vals_calc[$var] = $result_agrup;
                        }

                        $formula = str_replace('{' . $var . '}', $vals_calc[$var], $formula);
                    }
                }
                $this->logMessage("[Liquidación Retroactivo] 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'
                 * );
                 */
                $arrayParametros2 = $this->resultadoParametros($arrayParametros, $record_liq, $record_consulta, $vals_calc, $id_concep_nomina);


                /*
                 * Reemplazo de parametros(variables) a la formula
                 * Ejemplo: $arrayParametros = array(
                 * 'C1' => '1100',
                 * 'C2' => '55'
                 * );
                 */
                $formula = $this->reemplazoParametros($formula, $arrayParametros2);
                $this->logMessage("[Liquidación Retroactivo] 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) {
                    $this->logMessage("[Liquidación Retroactivo] Formula No cumple con la condicion: " . $formula);
                    $result = 0;
                }


                /*
                 * Acumulan resultados de liquidacion
                 */
                if ($result !== -9999) // Validar al cumplir condicion -9999 - no cumplue con la condicion de la formula
                    $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)
                     */
                    $porcentaje = $record_liq['porcentaje'];
                    if ($value['cod_tipo'] == 'V') {
                        $this->logMessage("[Liquidación Retroactivo] Formula CodTipo: " . $value['cod_tipo']);

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

                //Para calculo de prima servicios - 20190715
                //Si la formula es una, solo se ejecuta una vez - 20210826::LAVILA
                //Se verifico que sea por formula y no $porc_incre_salarial - 20210909::LAVILA
                if ($id_concep_nomina == 16) {
                    //break;
                }
            }
        } 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] Calcular porcentaje - " . $record_liq['porcentaje']);


                //Sumatoria de los valores de 1001 - 20170614
                //Sql
                $sql = <<<EOD
select sum(valor_liquidado) as valor_liquidado 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
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'];
                $this->logMessage("[Liquidación] porcentaje - " . $porcentaje . " :: valor_base - " . $valor_base);

                /*
                 * usa_dias_calen - 20160311
                 */
                if (!is_null($record_liq['num_dias'])) {
                    if ($record_liq['usa_dias_calen'] == 0) { //Mensual
                        $num_dias_pre = 30;
                        //Incidente #4012 <-> Se deja dias 30 para, que tome en base 30 - 20160719
                        //$num_dias_pre = $record_liq['num_dias']; // ? Revisar
                    } else { //Por días calendario
                        $num_dias_pre = $record_liq['num_dias'];
                    }
                    //para dias diferentes de  30 - 20160311
                    if ($num_dias_pre != 30) {
                        $result = ($result / 30) * $num_dias_pre;
                    }
                }
            } else {
                $this->logMessage("[Liquidación Retroactivo] 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;
                    $this->logMessage("[Liquidación Retroactivo] Num_dias - " . $num_dias);
                } else {
                    $num_dias = 'null';
                    $result = $record_liq['valor'];
                }
            }

            $valor_liquidado += $result;
        }

        /*
         * Valida creacion de registro
         */
        if ($valor_liquidado > 0) {

            //validar vacio en num_dias
            if (is_null($num_dias) || $num_dias == '') {
                $num_dias = 'null';
            }

            //Redondeo por decimales, hacia arriba, por calculo de AB en Autoliquidacion - 20171117
            //Se deja como estaba error ceil, se arreglo para que si no es por formula ni porcentaje, camcule correctamente, y no den decimales erroneos - 20171211, se colocaen retro el 20190611
            $valor_liquidado = CN_TABLE::ceiling($valor_liquidado, 1);

            $this->logMessage("[Liquidación Retroactivo] 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) 
            //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, id_periodo_ajuste ) 
        values ( $id_tipo_doc, '$num_doc', $id_concep_nomina, $id_periodo, round( $valor_liquidado, 0), 
        to_date('$fecha_desde','YYYY-MM-DD'), to_date('$fecha_hasta','YYYY-MM-DD'), $num_dias, round( $valor_base, 0), 
                    $porcentaje, $id_periodo_ajuste_conper ) 
EOD;
            //Ejecutar SQL
            CN_TABLE::executeSQL($sql);
        } else {

            $this->logMessage("[Liquidación Retroactivo] 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);
            $formula = str_replace($key, $value, $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, $record_consulta, $vals_calc, $id_concep_nomina_val) {

//        $logPath = sfConfig::get('sf_log_dir') . '/liquidacion.log';
//        $custom_logger = new sfFileLogger(new sfEventDispatcher(), array('file' => $logPath));
//
//        $custom_logger->info("[Liquidación] memory_get_usage ini resultadoParametros: " . CN_TABLE::convert(memory_get_usage()) . "\n");
        /*
         * 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] 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_consulta) > 0) {
//                $this->logMessage("[Liquidación] Caracter: " . $record_consulta[$caracter]['caracter'] . ", consulta: " . $record_consulta[$caracter]['consulta']);
//                die();
//                $consulta = $record[0]['consulta'];

                $this->logMessage("[Liquidación Retroactivo] Concat vals_calc: " . $caracter . $id_concep_nomina);

                /*
                 * Cambiar C por R, para que tome el valor del periodo liq la asignacion basica - 20150610
                 * Solo concepto bonificacion 1011 - 20170616
                 */
                $this->logMessage("[Liquidación Retroactivo] id_concep_nomina_val:: " . $id_concep_nomina_val);
                if ($id_concep_nomina_val == 11) {
                    $this->logMessage("[Liquidación Retroactivo] Cambiar C por R, para que tome el valor del periodo liq la asignacion basica:: " . $id_concep_nomina_val);
                    if ($caracter == 'C') {
                        if ($id_concep_nomina == 1) {
                            $caracter = 'R';
                        } else {
                            $caracter = 'J'; //Para conceptos que tienen valores sin formula y se ajustan manualmente - 20170622
                        }
                    }
                }
                /**
                 * Cambia C por D, para los conceptos de 1001, segun conceptos de vacaciones,
                 * toma valores segun id_periodo_ajuste - 20190612
                 */
                //Sql, valida concepto es de vacaciones
                $sql = <<<EOD
SELECT
    *
FROM no_concep_vac
where
id_concep_nomina = $id_concep_nomina_val   
EOD;
                $record = CN_TABLE::executeSQL($sql);
                if (count($record) > 0) {
                    $this->logMessage("[Liquidación Retroactivo] Cambia C por D, para los conceptos de 1001, segun conceptos de vacaciones:: " . $id_concep_nomina_val);
                    if ($caracter == 'C') {
                        if ($id_concep_nomina == 1) {
                            $caracter = 'D';
                        }
                    }
                }

                $this->logMessage("[Liquidación Retroactivo] Concat vals_calc:: " . $caracter . $id_concep_nomina);

                /**
                 * Se cambia consulta U por W, para treaer el ultimo registro encontrado por periodo de ajuste en liquidacion_nomina - 20170621
                 * Se inactiva el cambio de U por W ya que no esta tomando correctamente el concepto 1011 - 20220505::LAVILA
                 */
                if ($caracter . $id_concep_nomina == 'U11') {
                    $this->logMessage("[Liquidación Retroactivo] Cambio de ultimo valor por consulta W11->U11:: " . $caracter . $id_concep_nomina);
                    //$caracter = 'W';
                }

                if (!isset($vals_calc[$caracter . $id_concep_nomina])) {
                    $consulta = $record_consulta[$caracter]['consulta'];

                    /*
                     * Variables y estructura para manejo de consultas con variables bind - 20130829
                     */
                    //Reemplazo de $ por : para variables bind
//                $consulta = str_replace('$', ':', $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
                     * select nvl(sum(valor_liquidado),0) as valor from no_liquida_nomina where id_periodo = :periodo - ejemplo bind
                     */
                    //Sql
                    $sql = <<<EOD
$consulta  
EOD;
                    /*
                     * Variables y estructura para manejo de consultas con variables bind - 20130829
                     */
//                $record_var_bind = array(
//                    'id_tipo_doc' => 'id_tipo_doc',
//                    'num_doc' => 'num_doc',
//                    'id_concep_nomina' => 'id_concep_nomina',
//                    'id_periodo' => 'id_periodo'
//                );
                    //Get the variables within the consulta
//        $custom_logger->info("[Liquidación] memory_get_usage 1 resultadoParametros: " . CN_TABLE::convert(memory_get_usage()) . "\n");
//                $vars = array();
//                CN_TABLE::getVarsInConsulta($vars, $sql);
//                $record_var_bind = $vars;
////                var_dump($record_var_bind);
//                $record_bind = $record_liq;
//                $record_bind['id_concep_nomina'] = $id_concep_nomina;
                    //Ejecutar SQL
                    $record = CN_TABLE::executeSQL($sql);
//                $sql = str_replace("'", null, $sql);
//                $custom_logger->info("[Liquidación] memory_get_usage 2 resultadoParametros: " . CN_TABLE::convert(memory_get_usage()) . "\n");
//                $record = CN_TABLE::executeBindSQL($sql, null, $record_var_bind, $record_bind);
//                $custom_logger->info("[Liquidación] memory_get_usage 3 resultadoParametros: " . CN_TABLE::convert(memory_get_usage()) . "\n");
                    /*
                     * Validar registros SQL
                     */
                    if (count($record) > 0) {
                        $valor = $record[0]['valor'];
                    } else {
                        $valor = 0;
                    }
                    $vals_calc[$caracter . $id_concep_nomina] = $valor;
                }
                $valor = $vals_calc[$caracter . $id_concep_nomina];
            } else {
                $valor = 0;
            }

            $arrayParametros[$key] = $valor;

            $this->logMessage("[Liquidación Retroactivo] Valor por Caracter: " . $valor);
        }
        //Destruye una variable especificada
//        $custom_logger->info("[Liquidación] memory_get_usage pre resultadoParametros: " . CN_TABLE::convert(memory_get_usage()) . "\n");
//        unset($vars, $record_var_bind, $record_bind, $record_liq, $record, $key, $sql, $valor, $record_consulta, $consulta, $caracter);
//        $custom_logger->info("[Liquidación] memory_get_usage post resultadoParametros: " . CN_TABLE::convert(memory_get_usage()) . "\n");
        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();
        $arrayParametros = 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;
    }

    /**
     * Metodo para liquidar un periodo unicamente
     * 
     * @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, $tag_rn) {
        $this->logMessage("[Liquidación Retroactivo] Entro a liquidarRetroactivo");

        $i = 0;
        /*
         * Variable para optimizar consultas de formulas en las liquidaciones - 20140117
         */
        $vals_calc = array();

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

            /**
             * Consultar salario minimo
             */
            $salario_minimo = 550000;
            $porc_incre_salarial = 1;
            //Sql
            $sql = <<<EOD
(select nvl(valor_mensual, 0) as valor_mensual, nvl(porc_incre_salarial, 0) as porc_incre_salarial from no_smdlv where vigencia = extract(year from sysdate))  
EOD;
            //Ejecutar SQL
            $record_smlv = CN_TABLE::executeSQL($sql);

            if (count($record_smlv) > 0) {
                $salario_minimo = $record_smlv[0]['valor_mensual'];
                $porc_incre_salarial = $record_smlv[0]['porc_incre_salarial'];
            }

            /*
             * Tomar valores de NO_AJUSTE_NOMINA
             */
            if ($tag_rn == 1) {

                $id_periodos = '';
                /*
                 * Periodos de las vac, de meses anteriores al retro - 20150611
                 * Se cambia metodo por LISTAGG casos CEV - 20190705
                 */
                $sql = <<<EOD
  select 
        count(nov.num_doc) as cant,
        --to_char(wm_concat(DISTINCT nov.id_periodo)) as id_periodos
        LISTAGG(nov.id_periodo, ',') WITHIN GROUP (ORDER BY nov.id_periodo) as id_periodos

        from no_novedad_vac nov

        join no_periodo_v perv
        on perv.id_periodo = nov.id_periodo

        join no_concep_vac convac
        on nov.id_tipo_nov_vac = convac.id_tipo_nov_vac

        where nov.fecha_fin >= (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        /*between (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) 
          and (select per.fecha_fin from no_periodo per where per.id_periodo = $id_periodo_ajuste)*/
        --and nov.fecha_ini < (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) 
                        
        and perv.id_anhos != (select per.id_anhos from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        and perv.id_meses != (select per.id_meses from no_periodo per where per.id_periodo = $id_periodo_ajuste)
        and perv.fecha_fin < (select per.fecha_ini from no_periodo per where per.id_periodo = $id_periodo_ajuste) 
                    
        AND convac.id_concep_nomina = (select no_param_concep.id_concep_vacac from no_param_concep where no_param_concep.id_param_concep = 1)  
EOD;
                //Ejecutar SQL
                $recordss = CN_TABLE::executeSQL($sql);

                //validar que hay num_doc por la cant
                if (count($recordss) > 0 && isset($recordss[0]['cant']) && $recordss[0]['cant'] > 0) {

                    $id_periodos = ',' . $recordss[0]['id_periodos'];
                }


                //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,PORCENTAJE) 

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,
tab0.porcentaje       
from no_ajuste_nomina tab0
join no_periodo per
on per.id_periodo = tab0.id_periodo 
WHERE tab0.id_periodo = $id_periodo
and tab0.APLICAR_LIQ_CONCEP = 0                        
and tab0.id_periodo_ajuste in (25, 28, $id_periodo_ajuste $id_periodos )
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
EOD;
            } else {
                //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,PORCENTAJE) 

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,
tab0.porcentaje                       
from no_ajuste_nomina tab0
join no_periodo per
on per.id_periodo = tab0.id_periodo 
WHERE tab0.id_periodo = $id_periodo
and tab0.APLICAR_LIQ_CONCEP = 0
and tab0.id_periodo_ajuste in ( $id_periodo_ajuste )
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
EOD;
            }

            //Ejecutar SQL
            CN_TABLE::executeSQL($sql);


            /**
             * se filtran para vacaciones dias de periodos adicionales - 20140613
             * Se cambia metodo por LISTAGG casos CEV - 20190705
             */
            //Sql
            $sql = <<<EOD
select 
--to_char(wm_concat(id_periodo)) as  periodos
LISTAGG(id_periodo, ',') WITHIN GROUP (ORDER BY id_periodo) as periodos
from no_periodo
where id_anhos = (select id_anhos from no_periodo where id_periodo = $id_periodo_ajuste )
and id_meses = (select id_meses from no_periodo where id_periodo = $id_periodo_ajuste )
and id_tipo_periodo in (1 , 2)  
EOD;
            //Ejecutar SQL
            $record_per = CN_TABLE::executeSQL($sql);
            $periodos = $record_per[0]['periodos'];

            /*
             * Cargar Periodo-Funcionario-Concepto
             * 
             * Cargar Funcionarios
             * 
             * Para cada persona
             * 
             * Cargar conceptos que apliquen en periodo para la persona, en orden de ejecución
             */
            //No liquida conceptos entre 4000 y 4999 - 20130626
            //TODO: Revisar cantidad dias de vacaiones de periodos anteriores - 20130627
            /*
             * select 
              novvac.id_tipo_doc,
              novvac.num_doc,
              nvl(sum(dias_rango_mes(novvac.fecha_ini,novvac.fecha_fin,(select id_meses
              from NO_PERIODO where ID_PERIODO =  $id_periodo_ajuste))),0) as DIAS,
              NVL(SUM( NOVVAC.FECHA_FIN - NOVVAC.FECHA_INI + 1),0) as DIAS_VAC,
              --DIAS_RANGO_MES_SIN_TREINTAYUNO( NOVVAC.FECHA_INI, NOVVAC.FECHA_FIN, 1 ) as DIAS_vac_mes
              from no_novedad_vac novvac
              left join no_tipo_nov_vac tipnov on tipnov.id_tipo_nov_vac = novvac.id_tipo_nov_vac
              where TIPNOV.TIEMPO_LIQUI = 1

              and NOVVAC.ID_PERIODO = $id_periodo_ajuste
              /*
              and(
              NOVVAC.FECHA_INI 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_ajuste) ,'dd/mm/yyyy') ))
              or
              NOVVAC.FECHA_FIN 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_ajuste) ,'dd/mm/yyyy') ))
              or


              TO_DATE('01/'|| (select LPAD(ID_MESES,2,'0') ||'/'||ID_ANHOS from NO_PERIODO where ID_PERIODO = $id_periodo_ajuste) ,'dd/mm/yyyy') between novvac.fecha_ini and novvac.FECHA_FIN
              or
              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') )) between NOVVAC.FECHA_INI and NOVVAC.FECHA_FIN
              )
              group by NOVVAC.ID_TIPO_DOC, NOVVAC.NUM_DOC
              --, NOVVAC.FECHA_INI, novvac.FECHA_FIN
             */
            $filtro_per_aju = " and tab0.id_periodo_ajuste = $id_periodo_ajuste ";
            if ($tag_rn == 1) {
                $filtro_per_aju = " ";
            }
            //Sql
            /**
             * Se agrega dias de vac tambien de periodos adicionales - 20140311
             * Dias num ant para las bnoevdades de incapacidad - 20150224
             * Tag_retro para cuando es retroactivo, para retencion tiene encuenta todo el mes con lo del retroactivo - 20150610
             * Se agrega valor_uvt, valor_bonif - 20170613
             * Para calculo de prima servicios - 20190715
             * Se deja que calcule 4001 where-connom.codigo, para reintegro de asignacion basica por novedades que apliquen - 20211013::LAVILA
             */
            $sql = <<<EOD
select 
 
per.id_anhos as vig_ini,
1 as per_ini,
per.id_anhos as vig_fin,
per.id_meses as per_fin, 
                    
conka.id_concep_ka,
novka.id_novedad_kardex,
nvl(novka.num_dias_ant,0) as num_dias_ant,
row_number() over 
  ( partition by tab0.num_doc, tab0.id_concep_nomina order by tab0.id_concepto_periodo asc ) as rn, 
$salario_minimo as salario_minimo,
nvl('$porc_incre_salarial',0) as porc_incre_salarial,
0 as tag,
0 as tg_retro,
nvl((select valor_uvt from ts_uvt where vigencia = (select no_periodo.id_anhos from no_periodo where id_periodo = $id_periodo)) , 1) as valor_uvt,
nvl((select valor_fijo from no_concep_ab where id_concep_nomina in (select no_param_concep.id_concep_bonif from no_param_concep where no_param_concep.id_param_concep = 1)) , 1) as valor_bonif, 
tab0.*,
tab0.num_dias as dias_liq,
tab0.num_dias as meses_liq,
0 as dias_otra_ent,
0 as dias_ausenc,
nvl(vac.dias_vac,0) as wdiasv,
tipcon.orden,
connom.codigo,
connom.usa_dias_calen
                    
from no_concepto_periodo tab0

join no_periodo per
on per.id_periodo = $id_periodo_ajuste 

join no_concep_nomina connom
on connom.id_concep_nomina = tab0.id_concep_nomina

join no_tipo_concepto tipcon
on tipcon.id_tipo_concepto = connom.id_tipo_concepto

left join no_concep_ka conka
on conka.id_concep_nomina = tab0.id_concep_nomina

left join no_novedad_kardex novka
on novka.id_tipo_doc = tab0.id_tipo_doc
and novka.num_doc = tab0.num_doc
and novka.id_periodo = tab0.periodo
and novka.id_tip_nov_ka = conka.id_tip_nov_ka
and novka.estado = 1
and novka.fecha_ini = tab0.fecha_desde
and novka.fecha_fin = tab0.fecha_hasta
                    
left join (
    
    select 
 novvac.id_tipo_doc,                  
 novvac.num_doc,
 nvl(sum(dias_rango_mes(novvac.fecha_ini,novvac.fecha_fin,(select id_meses 
     from no_periodo where id_periodo =  $id_periodo_ajuste))),0) as dias,
 nvl(sum( novvac.fecha_fin - novvac.fecha_ini + 1),0) as num_dias_vac,
 nvl(sum(FECHA_RANGO_SIN_TREINTAYUNO(novvac.fecha_ini,novvac.fecha_fin)),0) as dias_vac
 from no_novedad_vac novvac
 left join no_tipo_nov_vac tipnov on tipnov.id_tipo_nov_vac = novvac.id_tipo_nov_vac
 where tipnov.tiempo_liqui = 1  and tipnov.operador = 1
     and novvac.id_periodo in ( $periodos )
 group by novvac.id_tipo_doc, novvac.num_doc
     
)vac
on vac.id_tipo_doc = tab0.id_tipo_doc and vac.num_doc = tab0.num_doc

where tab0.periodo = $id_periodo
$filtro_per_aju                   
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
and tab0.id_concep_nomina != (select id_concep_rete from no_param_concep where id_param_concep = 1)
and (tipcon.id_tipo_concepto = 1 or tipcon.id_tipo_concepto = 2)
and ( connom.codigo <= 4000 or connom.codigo >= 4999 or connom.codigo in (4001) )
                    
order by 
tab0.id_anhos,
tab0.id_meses,
tab0.id_tipo_doc,
tab0.num_doc,
tipcon.orden,
case 
  when connom.codigo >= 4000  
      then '0000'
  when connom.id_concep_nomina = (select no_param_concep.id_concep_bonif from no_param_concep where no_param_concep.id_param_concep = 1)  
      then '0001'
      else connom.codigo 
  end ,
tab0.id_concepto_periodo
--connom.codigo 
EOD;
            //Ejecutar SQL
            $records = CN_TABLE::executeSQL($sql);

            /*
             * Recorre los registros de funcionario - concepto nomina
             * para ser liquidados
             */
            $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);

            /*
             * Log liquidacion.log registros uno a uno - Funcionarios
             */
            $logPath = sfConfig::get('sf_log_dir') . '/liquidacion.log';
            $custom_logger = new sfFileLogger(new sfEventDispatcher(), array('file' => $logPath));
            $custom_logger->info("Mensual Inicio." . "\n");

            foreach ($records as $value) {

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

                $this->logMessage("[Liquidación Retroactivo] 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'];

                // Termina procesamiento de concepto
                $custom_logger->info("Procesado $i de $nom_conceptos_a_procesar conceptos. Documento: " . $num_doc . "\n");


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

                // Termina procesamiento de concepto
//                file_put_contents('/home/lavila/Escritorio/liquidacion.log', "Procesado $i de $nom_conceptos_a_procesar conceptos.\n", FILE_APPEND);
                $i++;
            }
            $custom_logger->info("Mensual Termino." . "\n");

            /**
             * Reliquidar FSP
             * Se toman conceptos segun la Tabla NO_FONDO_CONCEPTO para el id_descuento_ss = 2 
             */
            $valor_base = 0;

            /*
             * Se toman conceptos segun la 
             * Tabla NO_FONDO_CONCEPTO para el id_descuento_ss = 2 
             * Se agrega tag y periodo para la consulta de R - 20131216
             * Tag_retro para cuando es retroactivo, para retencion tiene encuenta todo el mes con lo del retroactivo - 20150610
             * Se agrega valor_uvt, valor_bonif - 20170613
             */
            //Sql
            $sql = <<<EOD
select
$salario_minimo as salario_minimo,
0 as tag,
0 as tg_retro,
nvl((select valor_uvt from ts_uvt where vigencia = (select no_periodo.id_anhos from no_periodo where id_periodo = $id_periodo)) , 1) as valor_uvt,
nvl((select valor_fijo from no_concep_ab where id_concep_nomina in (select no_param_concep.id_concep_bonif from no_param_concep where no_param_concep.id_param_concep = 1)) , 1) as valor_bonif, 
$id_periodo as periodo,  
tab0.* 
from no_liquida_nomina tab0
left join no_fondo_concepto foncon
on tab0.id_concep_nomina = foncon.id_concep_nomina
where foncon.id_descuento_ss = 2
and tab0.id_periodo = $id_periodo
and tab0.id_periodo_ajuste = $id_periodo_ajuste     
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc  
order by 
tab0.id_tipo_doc,
tab0.num_doc
EOD;

            //Ejecutar SQL
            $record_fsp = CN_TABLE::executeSQL($sql);
            $custom_logger->info("FSP Inicio." . "\n");
            $nom_conceptos_a_procesar += count($record_fsp);

            foreach ($record_fsp as $value) {

                $id_liquida_nomina = $value['id_liquida_nomina'];
                $valor_base = $value['valor_liquidado'];
                $valor_base_vac = 0;
                $num_doc = $value['num_doc'];
                $id_tipo_doc = $value['id_tipo_doc'];
                $num_dias_fsp = $value['num_dias'];
                $id_concep_nomina = $value['id_concep_nomina'];
                $vals_calc = array();

                $custom_logger->info(MemcacheHandler::getInstance()->get($progress_key) . " - FSP - Procesado $i de $nom_conceptos_a_procesar conceptos. Funcionario: " . $num_doc . "\n");

                //Dias para vacaciones
                //Se habilita novedvac para el periodo a liquidar - filtro id_periodo - 20130722 Se deshablita - 20130723
                //Toma los dias de vacaciones para el mes a liquidar - 20130723
                //Sql
                $sql = <<<EOD
select  nvl(sum(num_dias_vac),0) as dias_vac from (       
   select 
     novvac.id_tipo_doc,                  
     novvac.num_doc,
     nvl(sum(dias_rango_mes(novvac.fecha_ini,novvac.fecha_fin,(select id_meses 
         from no_periodo where id_periodo =  $id_periodo_ajuste))),0) as dias,
     nvl(sum( novvac.fecha_fin - novvac.fecha_ini + 1),0) as dias_vac,
     
     case when TIPNOV.operador = 1
     then nvl(sum(DIAS_RANGO_MES_SIN_TREINTAYUNO(novvac.fecha_ini,novvac.fecha_fin,(select id_meses from no_periodo where id_periodo =  $id_periodo_ajuste))),0) 
     else 0
     end as num_dias_vac
   
     from no_novedad_vac novvac
     left join NO_TIPO_NOV_VAC TIPNOV on TIPNOV.ID_TIPO_NOV_VAC = NOVVAC.ID_TIPO_NOV_VAC
     where TIPNOV.TIEMPO_LIQUI = 1 
     --and NOVVAC.ID_PERIODO = $id_periodo_ajuste
     and (
             novvac.fecha_ini 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_ajuste) ,'dd/mm/yyyy') )) 
             or
             novvac.fecha_fin 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_ajuste) ,'dd/mm/yyyy') )) 

             or        


             to_date('01/'|| (select lpad(id_meses,2,'0') ||'/'||id_anhos from no_periodo where id_periodo = $id_periodo_ajuste) ,'dd/mm/yyyy') between novvac.fecha_ini and novvac.fecha_fin
             or
             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') )) between novvac.fecha_ini and novvac.fecha_fin
    )
     and novvac.NUM_DOC = $num_doc
     group by novvac.id_tipo_doc, novvac.num_doc, TIPNOV.operador
)
EOD;

                //Ejecutar SQL
                $record_vac = CN_TABLE::executeSQL($sql);
                /*
                 * Calcular IBC para vacaciones
                 */
                // Se agrega al calculo la formula (({A39}/30)*$wdiasv)) - 20130517
                // Toma los dias de vacaciones para el mes a liquidar
                $wdiasv = 0;
                if (count($record_vac) > 0) {
                    $wdiasv = $record_vac[0]['dias_vac'];
                }

                $formula = "(({A39}/30)*$wdiasv)";
                $this->logMessage("[Liquidación Vac] Formula Inicial: " . $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 Vac] Agrupacion: " . $agrup);

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

                $arrayParametros = $this->parametrosFormula($formula);
                $arrayParametros = $this->resultadoParametros($arrayParametros, $value, $record_consulta, $vals_calc, $id_concep_nomina);

                $formula = $this->reemplazoParametros($formula, $arrayParametros);
                /*
                 * 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 Vac] Formula No cumple con la condicion: " . $formula);
                    $result = 0;
                }
                //Valor base de IBC vacaciones
                $valor_base_vac = round($result, -3);
                $this->logMessage("[Liquidación Vac] Valor base de IBC vacaciones: " . $valor_base_vac);

                /*
                 * Valor base formula FSP
                 */
                $valor_base = round($valor_base, -3);
//                $valor_base = round($valor_base);
                //valor base no puede superar 25 salarios minimos
                if ($valor_base > ($salario_minimo * 25)) {
                    $valor_base = round(($salario_minimo * 25) - 1, -3);
//                    $valor_base = round(($salario_minimo * 25) - 1);
                }


                /*
                 * Variables del concepto 1 asignacion basica para los dias de liquidacion y totales de vacaciones - 20131216
                 * Anexo de conceptos de enfermedad por el tipo de novedad que causa liquidacion - 20131217
                 */
                //Sql
                $sql = <<<EOD
select 
tab0.id_tipo_doc,
tab0.num_doc,
--tab0.id_concep_nomina,
--sum(tab0.num_dias) as dias_liq,
sum(case when connom.operador = 1 then tab0.num_dias else tab0.num_dias*(-1) end ) as dias_liq,
max(nvl(vac.dias_vac,0)) as wdiasv

from no_concepto_periodo tab0

join no_concep_nomina connom
on connom.id_concep_nomina = tab0.id_concep_nomina

join no_tipo_concepto tipcon
on tipcon.id_tipo_concepto = connom.id_tipo_concepto
                    
left join (
    
    select 
    novvac.id_tipo_doc,                  
    novvac.num_doc,
    nvl(sum(dias_rango_mes(novvac.fecha_ini,novvac.fecha_fin,(select id_meses 
        from no_periodo where id_periodo =  $id_periodo_ajuste))),0) as dias,
    nvl(sum( novvac.fecha_fin - novvac.fecha_ini + 1),0) as num_dias_vac,
    nvl(sum(FECHA_RANGO_SIN_TREINTAYUNO(novvac.fecha_ini,novvac.fecha_fin)),0) as dias_vac
                        
    from no_novedad_vac novvac
    left join no_tipo_nov_vac tipnov on tipnov.id_tipo_nov_vac = novvac.id_tipo_nov_vac
    where tipnov.tiempo_liqui = 1 and tipnov.operador = 1
     and novvac.id_periodo in ( $periodos )
    group by novvac.id_tipo_doc, novvac.num_doc

)vac
on vac.id_tipo_doc = tab0.id_tipo_doc and vac.num_doc = tab0.num_doc

where tab0.periodo = $id_periodo
and tab0.num_doc = $num_doc
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.id_periodo_ajuste = $id_periodo_ajuste                        

and ( 
  tab0.id_concep_nomina in (select id_concep_rein from no_concep_nomina where id_concep_nomina = (select no_param_concep.ID_CONCEP_BASICA from no_param_concep where id_param_concep = 1)) 
  or tab0.id_concep_nomina in (select id_concep_ajuste from no_concep_nomina where id_concep_nomina = (select no_param_concep.ID_CONCEP_BASICA from no_param_concep where id_param_concep = 1)) 
  or  tab0.id_concep_nomina = (select no_param_concep.ID_CONCEP_BASICA from no_param_concep where id_param_concep = 1) 
  or tab0.id_concep_nomina in (SELECT DISTINCT
    kar.ID_CONCEP_NOMINA 
    FROM NO_CONCEP_KA kar
    join NO_TIP_NOV_KA tipkar
    on tipkar.ID_TIP_NOV_KA = kar.ID_TIP_NOV_KA
    where tipkar.CAUSA_LIQUIDACION = 1) 
)
                        
and tipcon.id_tipo_concepto != 4
             
group by
tab0.id_tipo_doc,
tab0.num_doc
    --,tab0.id_concep_nomina  
EOD;
                //Ejecutar SQL
                $record_smlv = CN_TABLE::executeSQL($sql);

                if (count($record_smlv) > 0) {
                    $dias_liq = $record_smlv[0]['dias_liq'];
                    $wdiasv_tot = $record_smlv[0]['wdiasv'];
                }

                //Anexo dias totales y de vacaciones totales - 20131217
                $array_valor_base = $this->valor_base_fsp($valor_base, $salario_minimo, $valor_base_vac, $wdiasv_tot, $dias_liq, $num_doc, $id_periodo_ajuste);
                $valor_fsp = $array_valor_base['valor_fsp'];
                $porcentaje_fsp = $array_valor_base['porcentaje_fsp'];

                /**
                 * SQL de consulta para validar si el concepto de FSP es por ajuste - 20131129
                 */
                //Sql
                $sql = <<<EOD
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.porcentaje
from no_ajuste_nomina tab0
join no_periodo per
on per.id_periodo = tab0.id_periodo 
WHERE tab0.id_periodo = $id_periodo 
and tab0.APLICAR_LIQ_CONCEP = 0
and tab0.id_periodo_ajuste = $id_periodo_ajuste                        
and tab0.NUM_DOC = $num_doc
and tab0.id_concep_nomina = $id_concep_nomina
EOD;

                //Ejecutar SQL
                $record_fsp_ver = CN_TABLE::executeSQL($sql);

                /*
                 * Validar si el FSP es por ajuste - 20131129
                 */
                $val_fsp_aju = 0;
                if (count($record_fsp_ver) != 0) {
                    $val_fsp_aju = $record_fsp_ver[0]['valor_ajuste'];
                    //Campo porcentaje para FSP - 20230724::LAVILA
                    if ($record_fsp_ver[0]['porcentaje'] != null) {
                        $porcentaje_fsp = $record_fsp_ver[0]['porcentaje'];
                    }
                }
                //if (count($record_fsp_ver) == 0) {
                if ($valor_fsp > 0) {

                    /*
                     * Actualizar valores de FSP
                     */
                    //sentencia sql
                    $sql = <<<EOD
update NO_LIQUIDA_NOMINA set valor_liquidado =  $valor_fsp + $val_fsp_aju
        , porcentaje = $porcentaje_fsp
            , valor_base = round( valor_liquidado, -3 ) 
    where id_liquida_nomina = $id_liquida_nomina 
        and id_periodo = $id_periodo
        and id_periodo_ajuste = $id_periodo_ajuste     
EOD;
                    //ejecuta y obtiene el resultado del sql
                    CN_TABLE::executeSQL($sql);
                } else {

                    /*
                     * Borrar del FSP
                     */
                    //sentencia sql
                    $sql = <<<EOD
delete from NO_LIQUIDA_NOMINA where id_liquida_nomina = $id_liquida_nomina 
and id_periodo = $id_periodo
and id_periodo_ajuste = $id_periodo_ajuste     
EOD;
                    //ejecuta y obtiene el resultado del sql
                    CN_TABLE::executeSQL($sql);
                }
                //}

                $i++;
            }

            $custom_logger->info("FSP Termino." . "\n");

            /*
             * Inicio del proceso de calculo de Retencion en la fuente concepto 2001
             * Tag_retro para cuando es retroactivo, para retencion tiene encuenta todo el mes con lo del retroactivo - 20150610
             * Solo retefunte
             * Se agrega valor_uvt, valor_bonif - 20170613
             */
            //Sql
            $sql = <<<EOD
select 
0 as tag,
1 as tg_retro,
nvl((select valor_uvt from ts_uvt where vigencia = (select no_periodo.id_anhos from no_periodo where id_periodo = $id_periodo)) , 1) as valor_uvt,
nvl((select valor_fijo from no_concep_ab where id_concep_nomina in (select no_param_concep.id_concep_bonif from no_param_concep where no_param_concep.id_param_concep = 1)) , 1) as valor_bonif, 
tab0.*,
tab0.num_dias as dias_liq,
tipcon.orden,
connom.codigo,
connom.usa_dias_calen
from no_concepto_periodo tab0

join no_concep_nomina connom
on connom.id_concep_nomina = tab0.id_concep_nomina

join no_tipo_concepto tipcon
on tipcon.id_tipo_concepto = connom.id_tipo_concepto

where tab0.periodo = $id_periodo
and tab0.id_periodo_ajuste = $id_periodo_ajuste     
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
and tab0.id_concep_nomina = (select id_concep_rete from no_param_concep where id_param_concep = 1)
and tab0.porcentaje > 0

order by 
tab0.id_anhos,
tab0.id_meses,
tab0.id_tipo_doc,
tab0.num_doc,
tipcon.orden,
connom.codigo 
EOD;
            //Ejecutar SQL
            //$records = CN_TABLE::executeSQL($sql);

            /*
             * Recorre los registros de funcionario - concepto nomina
             * para ser liquidados
             */
//            $i = 0;
//            $nom_conceptos_a_procesar = count($records);
//            foreach ($records as $value) {
//                $this->logMessage("[Liquidación Retroactivo] 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, $record_consulta, $id_periodo_ajuste);
//
//                // Termina procesamiento de concepto
////                file_put_contents('/home/lavila/Escritorio/liquidacion.log', "RETE - Procesado $i de $nom_conceptos_a_procesar conceptos.\n", FILE_APPEND);
////                $i++;
////                $custom_logger->info(MemcacheHandler::getInstance()->get($progress_key) . " - RETE - Procesado $i de $nom_conceptos_a_procesar conceptos. Funcionario: " . $num_doc . "\n");
//            }
            //Commit de las transacciones
            $this->conn->commit();
            $custom_logger->info("Commit de las transacciones" . "\n");
        } catch (Exception $exc) {
            $this->logMessage("[Liquidación Retroactivo] ERROR!!! liquidarRetroactivo");
            $this->conn->rollback();
        }
    }

}
