<?php

/**
 * inf_base_calc_rete actions.
 *
 * @package    nomina
 * @subpackage inf_base_calc_rete
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class inf_base_calc_reteActions extends sfQuery {
    /*
     * ------------VARIABLES PARA SERVICIOS DE CONSULTA - LIST
     */

    protected $table_names = array(
        'NO_CAL_RETEFUENTE',
        'TIPO_DOCUMENTO',
        'NO_DATOS_FUNCIONARIO_V',
        'NO_PERIODO_V'
    ); //tablas para construir el sql, por medio de joins
    protected $table_join_ids = array(
        'TIPO_DOCUMENTO' =>
        array(
            'id_tipo_doc' => 'NO_CAL_RETEFUENTE'
        ),
        'NO_DATOS_FUNCIONARIO_V' =>
        array(
            'id_tipo_doc' => 'NO_CAL_RETEFUENTE',
            'num_doc' => 'NO_CAL_RETEFUENTE'
        ),
        'NO_PERIODO_V' =>
        array(
            'id_periodo' => 'NO_CAL_RETEFUENTE'
        )
    ); //si posee tablas para joins, identificar la relacion de los campos con las tablas
    protected $fields = array(
        'NO_CAL_RETEFUENTE' =>
        array(
            'id_calc_retefuente' => 'id_calc_retefuente',
            'id_periodo' => 'id_periodo',
            'id_tipo_doc' => 'id_tipo_doc',
            'num_doc' => 'num_doc',
            'fecha_ingreso' => 'fecha_ingreso',
            'diastot' => 'diastot',
            'totdev' => 'totdev',
            'apopen' => 'apopen',
            'apofsp' => 'apofsp',
            'apovol' => 'apovol',
            'subtot1' => 'subtot1',
            'c25_exec' => 'c25_exec',
            'subtot2' => 'subtot2',
            'dividido13' => 'dividido13',
            'aposal_obl' => 'aposal_obl',
            'diasal_obl' => 'diasal_obl',
            'des_salobl' => 'des_salobl',
            'cer_saledu' => 'cer_saledu',
            'max_saledu' => 'max_saledu',
            'des_saledu' => 'des_saledu',
            'cer_intere' => 'cer_intere',
            'max_intere' => 'max_intere',
            'des_intere' => 'des_intere',
            'ingr_prome' => 'ingr_prome',
            'prom_uvts' => 'prom_uvts',
            'tar_margi' => 'tar_margi',
            'men_prouvt' => 'men_prouvt',
            'maspuntos' => 'maspuntos',
            'reten_uvts' => 'reten_uvts',
            'reten' => 'reten',
            'reten_ante' => 'reten_ante',
            'sum_rent_deduc' => 'sum_rent_deduc',
            'c40_exec' => 'c40_exec',
            'adic_subtot3' => 'adic_subtot3',
            'subtot3' => 'subtot3'
        ),
        'TIPO_DOCUMENTO' =>
        array(
            'descripcion' => 'descripcion',
            'abreviacion' => 'abreviacion'
        ),
        'NO_DATOS_FUNCIONARIO_V' =>
        array(
            'primer_nombre' => 'primer_nombre',
            'segundo_nombre' => 'segundo_nombre',
            'primer_apellido' => 'primer_apellido',
            'segundo_apellido' => 'segundo_apellido',
            'primer_nombre,||, ,||,segundo_nombre' => 'nombre',
            'nombre_completo' => 'nombre_completo',
            'nombre_apellido' => 'nombre_apellido'
        ),
        'NO_PERIODO_V' =>
        array(
            'id_anhos' => 'id_anhos',
            'id_meses' => 'id_meses',
            'id_anhos,||, ,||,id_meses' => 'periodo_mes',
            'id_tipo_periodo' => 'id_tipo_periodo',
            'periodo' => 'periodo'
        )
    ); //por cada tabla especificar los campos del select

    /*
     * OPCIONES DE FILTRO:
     *
     * LIKEALLPLUS- busqueda comparativa de la cadena dividida por los espacios en blanco en cualquier posición
     * LIKEALL - busqueda comparativa de la cadena en cualquier posición
     * LIKE - busqueda en la cadena que inicie por la variable de filtro
     *
     * rownum,start - rownum,end / estos campos para uso del Grid live GWT, numero fijo de filas de consulta
     */
    protected $table_field_conditions = array(
        'NO_CAL_RETEFUENTE' => array(
            'id_calc_retefuente,a' => array('!=' => array(-1)),
            'id_calc_retefuente,b' => array('=' => array('id_calc_retefuente')),
            'id_tipo_doc' => array('=' => array('id_tipo_doc')),
            'num_doc' => array('=' => array('num_doc')),
            'id_periodo' => array('=' => array('id_periodo_filtro')),
            'rownum,start' => array('>' => array('_startRow')),
            'rownum,end' => array('<=' => array('_endRow'))
        )
    ); //por cada tabla se dan los campos, opcion de filtro y variable que entra para los posibles filtros
    protected $table_field_or_conditions = array(); // filtros de condicion or
    protected $fields_orderBy = array(
        'id_periodo', 'id_tipo_doc', 'num_doc'
    ); //campos para el ordenamiento de la consulta
//    protected $table_field_obligatory = array('id_debito'); //campos obligatorios de filtro - estan en el request

    /*
     * Variables manejo de log
     */
    //true - consulta de administracion
    protected $is_admin = false;
    //si es servicio para filtro agregar campo
    protected $filtro = 'Informe Base Calculo Retefuente';
    //true - la tabla principal de busqueda no es una vista
    protected $is_filtro = false;


    /*
     * ------------VARIABLES PARA SERVICIO DE SUMATORIA - SUM
     *
     */
//    protected $summatory_data = array(
//        'NO_CAL_RETEFUENTE' => array(
//            'fields' => array(
////                'nvl(asignacion_basica,0)#asignacion_basica',
//                'nvl(valor_liquidado,0)#valor_liquidado',
//                'nvl(valor_base,0)#valor_base'
//            ),
//            'labels' => array('num_doc,Total'),
//            'count' => 'abreviacion'
//        )
//    ); //se especifica por tabla los campos de suma y condiciones de filtro

    /**
     * Construccion de observacion perzonalizada
     * 
     * Toda variable para tomarla del request con el formato:
     * &request-variable&
     * 
     * false - observacion por defecto
     *
     * @var string 
     */
    protected $observacion_list = false;
    protected $observacion_add = false;
    protected $observacion_update = false;
    protected $observacion_remove = false;

    // Validate

    /**
     * Ejecuta una validación previa a la ejecución de una operación tipo Add
     *
     * @param sfWebRequest $request
     * @return array 
     */
    protected function validateAdd(sfWebRequest $request) {

        //valor por defecto
        $errors = null;

        /*
         * Variables request
         */

        /*
         *  Validar la operación, ya sea por SQL
         */

        /*
         *  Generar errores en $errors
         */

        return $errors;
    }

    /**
     * Ejecuta una validación previa a la ejecución de una operación tipo Update
     *
     * @param sfWebRequest $request
     * @return array 
     */
    protected function validateUpdate(sfWebRequest $request) {

        //valor por defecto
        $errors = null;

        /*
         * Variables request
         */

        /*
         *  Validar la operación, ya sea por SQL
         */
        /*
         *  Generar errores en $errors
         */

        return $errors;
    }

    /**
     * Ejecuta una validación previa a la ejecución de una operación tipo Remove
     *
     * @param sfWebRequest $request
     * @return array 
     */
    protected function validateRemove(sfWebRequest $request) {

        //valor por defecto
        $errors = null;

        /*
         *  Validar la operación, ya sea por SQL
         */

        /*
         *  Generar errores en $errors
         */

        return $errors;
    }

    /**
     * Acciones anteriores a la original
     * 
     * return sfWebRequest Changed Request with additional parameters.
     * 
     * @param type $Action ( ADD, UPDATE, REMOVE )
     * @param sfWebRequest $request
     * @return \sfWebRequest 
     */
    protected function preprocessRequest($Action, sfWebRequest $request) {

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

        /*
         * Procesar Request
         */
        //accion add
        if ($Action == "ADD") {
            
        }

        //accion update
        if ($Action == "UPDATE") {
            
        }

        //accion remove
        if ($Action == "REMOVE") {
            
        }

        return $request;
    }

    /**
     * Acciones posteriores a la original
     * 
     * return sfWebRequest Changed Request with additional parameters.
     * 
     * @param type $Action ( ADD, UPDATE, REMOVE )
     * @param sfWebRequest $request
     * @return \sfWebRequest 
     */
    protected function postprocessRequest($Action, sfWebRequest $request, $list_data_post) {

        /*
         * Se instancia la clase del manejo del log
         */
        $logger = sfContext::getInstance()->getLogger();
        $logger->info("Entro a postprocessRequest - " . $list_data_post);

        /*
         * Procesar Request
         */
        //accion add
        if ($Action == "ADD") {
            
        }

        //accion update
        if ($Action == "UPDATE") {
            
        }

        //accion remove
        if ($Action == "REMOVE") {
            
        }

        return $request;
    }

    /**
     * Calcular ReteFuente
     * Procedimiento 2 de calculo de retefuente:
     * Enero - Diciembre a Noviembre
     * Julio - Junio a Mayo
     *
     * @param sfRequest $request A request object
     */
    public function executeAdd(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");


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

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

        try {


            /*
             * (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++;
            }

            /**
             * 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[''] = '';

            /**
             * Variables de filtro
             */
            //Rango fecha
            $vig_ini = $request['vig_ini'];
            $vig_fin = $request['vig_fin'];
            $per_ini = $request['per_ini'];
            $per_fin = $request['per_fin'];

            //id_periodo
            $id_periodo = $request['id_periodo_filtro'];
            $username = $request['username'];
            $progress_key = $request['progress_key'] . $username;

            //id_agrup_concepto
            $id_agrup_dev = $request['id_agrup_dev'];
            $id_agrup_apovol = $request['id_agrup_apovol'];

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

            /*
             * Validar UVT
             * Se cambia para tomar la vigencia final - 20180515
             */
            //Sql
//            $sql = <<<EOD
//select * from ts_uvt where vigencia = (select no_periodo_v.id_anhos from no_periodo_v where id_periodo = $id_periodo)
//EOD;
            $sql = <<<EOD
select * from ts_uvt where vigencia = $vig_fin
EOD;
            //Ejecutar SQL
            $rec_uvt = CN_TABLE::executeSQL($sql);
            //Sql
//            $sql = <<<EOD
//select * from ts_uvt where vigencia = (select no_periodo_v.id_anhos - 1 from no_periodo_v where id_periodo = $id_periodo) 
//EOD;
            $sql = <<<EOD
select * from ts_uvt where vigencia = $vig_ini 
EOD;
            //Ejecutar SQL
            $rec_uvtant = CN_TABLE::executeSQL($sql);

            $uvt = 0;
            $uvt_ant = 0;
            //Validar si hay $uvt
            if (count($rec_uvt) > 0 && count($rec_uvtant) > 0) {
                $uvt = $rec_uvt[0]['valor_uvt'];
                $uvt_ant = $rec_uvtant[0]['valor_uvt'];


                /*
                 *  Borrar datos anteriores Periodo-Funcionario
                 */
                //Sql
                $sql = <<<EOD
DELETE FROM NO_CAL_RETEFUENTE tab0 WHERE tab0.id_periodo = $id_periodo
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
EOD;
                //Ejecutar SQL
                CN_TABLE::executeSQL($sql);

                /**
                 * Traer funcionarios activos para el periodo
                 * Tag_retro para cuando es retroactivo, para retencion tiene encuenta todo el mes con lo del retroactivo - 20150610
                 * Omitir procedimiento 1 - 20190712
                 * Se agrega para solicitud de continuidad - 20190715
                 */
                //Sql
                $sql = <<<EOD
select 
1 as tag,
1 as tg_retro,
'' as id_periodo_ajuste,
$vig_ini as vig_ini,
$vig_fin as vig_fin,
$per_ini as per_ini,
$per_fin as per_fin,    
tab0.*,
nombra.id_nombramiento,
nombra.fecha_nombra,
--Se agrega para solicitud de continuidad - 20190715
--nombra.fecha_ingreso,
case when nombra.solucion_continuidad = 0 then nombra.fecha_ingreso 
    else (
        nvl((
          select max(nom_ult.fecha_ingreso) as fecha_ingreso from no_nombramiento nom_ult 
          where tab0.id_tipo_doc = nom_ult.id_tipo_doc
          and tab0.num_doc = nom_ult.num_doc
          and nom_ult.estado = 0
          and nom_ult.id_nombramiento != nombra.id_nombramiento
        ),nombra.fecha_ingreso)
    )
    end as fecha_ingreso,
nombra.fecha_termina,
 to_date( '01/'||lpad($per_ini, 2, '0')||'/' || ($vig_ini), 'dd/mm/yyyy') as fecha_ini,
TRUNC(LAST_DAY( to_date(lpad($per_fin, 2, '0') || '/' || ($vig_fin), 'mm/yyyy')  )) as fecha_fin
from no_estado_func_v tab0

join no_nombramiento_v nombra
on tab0.id_tipo_doc = nombra.id_tipo_doc
and tab0.num_doc = nombra.num_doc

WHERE tab0.periodo = $id_periodo
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
--and nombra.fecha_ingreso <= TRUNC(LAST_DAY( to_date(12 || '/' || (tab0.id_anhos-1), 'mm/yyyy')  ))
and tab0.num_doc not in ( 
    select 
    num_doc
    from (
           SELECT
           aut.*,
           ROW_NUMBER() OVER (
            partition by aut.num_doc
            ORDER BY aut.ESTADO desc, aut.ID_NOVEDAD_PROCED_RETE desc
           ) AS rn
          from no_novedad_proced_rete aut
    )aut

    where
    aut.id_tipo_proced_rete = 1 
    and aut.rn = 1    
)
                        
order by
tab0.id_anhos,
tab0.id_tipo_doc,
tab0.id_meses,
tab0.num_doc 
EOD;
                //Ejecutar SQL
                $records = CN_TABLE::executeSQL($sql);

                //Validar si hay funcionarios para liquidación
                if (count($records) > 0) {
                    $this->logMessage("[Informe Base Calculo ReteFuente] Validar si hay funcionarios para calcular retefuente.");

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

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

                    $this->logMessage("[Informe Base Calculo ReteFuente] nom_conceptos_a_procesar: " . $nom_conceptos_a_procesar);
                    foreach ($records as $record) {

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

                        $this->logMessage("[Informe Base Calculo ReteFuente] Existen calcular retefuente. NumDoc: " . $record['num_doc']);

                        /*
                         * Datos por record
                         */
                        $num_doc = $record['num_doc'];
                        $id_tipo_doc = $record['id_tipo_doc'];
                        $fecha_ingreso = $record['fecha_ingreso'];
                        $fecha_termina = $record['fecha_termina'];
                        $fecha_ini = $record['fecha_ini'];
                        $fecha_fin = $record['fecha_fin'];


                        /**
                         * Datos anexos para calculo de tabla NO_CAL_RETEFUENTE_HIST
                         */
                        $dias_liq = 0;
                        $valor_liquidado = 0;
                        $apopen = 0;
                        $apofsp = 0;
                        $apovol = 0;
                        $aposal_obl = 0;
                        $diasal_obl = 0;
                        $cer_cerdep = 0;
                        $max_cerdep = 0;
                        $des_cerdep = 0;
                        $subtot1 = 0;

                        //sql
                        $sql = <<<EOD
select tab0.* from no_cal_retefuente_hist tab0
WHERE tab0.id_periodo = $id_periodo
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc 
EOD;
                        //Ejecutar SQL
                        $records_cal_hist = CN_TABLE::executeSQL($sql);
                        if (count($records_cal_hist) > 0) {
                            $dias_liq = $records_cal_hist[0]['diastot'];
                            $valor_liquidado = $records_cal_hist[0]['totdev'];
                            $apopen = $records_cal_hist[0]['apopen'];
                            $apofsp = $records_cal_hist[0]['apofsp'];
                            $apovol = $records_cal_hist[0]['apovol'];
                            $aposal_obl = $records_cal_hist[0]['aposal_obl'];
                            $diasal_obl = $records_cal_hist[0]['diasal_obl'];
                        }



                        /*
                         * Calcular los dias a liquidar (ausencias no afectan antiguedad)
                         */
                        $dias_liq += $this->diasLiquidar($id_periodo, $num_doc, $id_tipo_doc, $fecha_ini, $fecha_fin, $fecha_ingreso, $fecha_termina, $value);
                        $this->logMessage("[Liquidación Agrupación] Dias de Liquidación: " . $dias_liq);


                        /**
                         * Recorrer Agrupaciones
                         */
                        $arrayParametros = array();

                        /*
                         * Cambio de A1 por relacion con los conceptos C1
                         * Ejemplo: 'A1' => '0'
                         */
                        $agrup = $this->reemplazoAgrupacion($id_agrup_dev);
                        $this->logMessage("[Informe Base Calculo ReteFuente] Agrupacion: " . $agrup);


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


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


                        /*
                         * Reemplazo de parametros(variables) a la formula
                         * Ejemplo: $arrayParametros = array(
                         * 'C1' => '1100',
                         * 'C2' => '55'
                         * );
                         */
                        $formula = $agrup;
                        $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("[Informe Base Calculo ReteFuente] Formula No cumple con la condicion: " . $formula);
                            $result = 0;
                        }
                        $valor_liquidado += $result;


                        /**
                         * Recorrer Agrupaciones
                         */
                        $arrayParametros = array();

                        /*
                         * Cambio de A1 por relacion con los conceptos C1
                         * Ejemplo: 'A1' => '0'
                         */
                        $agrup = $this->reemplazoAgrupacion($id_agrup_apovol);
                        $this->logMessage("[Informe Base Calculo ReteFuente] Agrupacion: " . $agrup);


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


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


                        /*
                         * Reemplazo de parametros(variables) a la formula
                         * Ejemplo: $arrayParametros = array(
                         * 'C1' => '1100',
                         * 'C2' => '55'
                         * );
                         */
                        $formula = $agrup;
                        $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("[Informe Base Calculo ReteFuente] Formula No cumple con la condicion: " . $formula);
                            $result = 0;
                        }
                        $apovol += $result;

                        /*
                         * Calculo de liquida aportes
                         */

                        /*
                         * Para calcular pension y fondo solidaridad por rango de meses y anhos
                         * Se debe tener encuenta valores de retroactivo en el calculo - 20140106
                         * Segun revision la pension y fsp se calcula del rango de periodos seleccionados - 20140107 
                         */
                        //sql
//                        $sql = <<<EOD
//select
//tab.id_tipo_doc,
//tab.num_doc,
//sum(valor_pen_a + case when valor_pen_c > 0 then valor_pen_c else 0 end  ) as valor_pen,
//sum(valor_fsp_a + case when valor_fsp_c > 0 then valor_fsp_c else 0 end) as valor_fsp,
//sum(valor_sal_a + case when valor_sal_c > 0 then valor_sal_c else 0 end) as valor_sal,
//sum(dias_sal) as dias_sal
//
//from
//(
//
//    select
//    tab.id_tipo_doc,
//    tab.num_doc,
//    tab.ID_PERIODO,
//    /*
//    count(tab.ID_PERIODO),
//    tab.TIPO_PLANILLA,
//    */
//    nvl( sum( tab.aporte_func ) ,0) as total,
//    nvl( sum( case when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'A' then tab.aporte_func else 0 end ) ,0) as valor_pen_a,
//    nvl( sum(
//    case when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
//          when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'C' then tab.aporte_func 
//          else 0 end 
//    ) ,0) as valor_pen_c,
//    
//    nvl( sum( case when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'A' then tab.aporte_func else 0 end ) ,0) as valor_fsp_a,
//    nvl( sum(
//    case when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
//          when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'C' then tab.aporte_func 
//          else 0 end 
//    ) ,0) as valor_fsp_c,
//    
//    nvl( sum( case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.aporte_func else 0 end ) ,0) as valor_sal_a,
//    nvl( sum(
//    case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
//          when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'C' then tab.aporte_func 
//          else 0 end 
//    ) ,0) as valor_sal_c,
//    
//    nvl( sum( case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.num_dias else 0 end ) ,0) as dias_sal
//    
//    from
//    (
//      
//        select
//        liqapo.id_tipo_doc,
//        liqapo.num_doc,
//        liqapo.ID_PERIODO,
//        des.id_descuento_ss,
//        liqapo.aporte_func,
//        liqapo.TIPO_PLANILLA,
//        liqapo.num_dias
//        /*
//        nvl( sum( liqapo.aporte_func ) ,0) as total,
//        nvl( sum( case when des.id_descuento_ss = 1 then liqapo.aporte_func else 0 end ) ,0) as valor_pen,
//        nvl( sum( case when des.id_descuento_ss = 2 then liqapo.aporte_func else 0 end ) ,0) as valor_fsp,
//        nvl( sum( case when des.id_descuento_ss = 3 then liqapo.aporte_func else 0 end ) ,0) as valor_sal,
//        nvl( sum( case when des.id_descuento_ss = 3 then liqapo.num_dias else 0 end ) ,0) as dias_sal
//        */
//        from no_liquida_aporte liqapo
//        
//        join no_concep_nomina concep
//        on liqapo.id_concep_nomina = concep.id_concep_nomina
//        and liqapo.id_clase_fondo = concep.id_clase_fondo
//        
//        join no_fondo_concepto foncon
//        on foncon.id_concep_nomina = concep.id_concep_nomina
//        and foncon.id_mae_fondos = liqapo.id_mae_fondos
//        
//        join no_descuento_ss des
//        on foncon.id_descuento_ss = des.id_descuento_ss
//        
//        join no_clase_fondo cla
//        on  concep.id_clase_fondo = cla.id_clase_fondo
//        
//        join no_periodo_v per
//        on per.id_periodo = liqapo.id_periodo
//        
//        where 
//        per.id_anhos || lpad(per.id_meses, 2, '0') between  $vig_ini || lpad( $per_ini, 2, '0')  and $vig_fin || lpad( $per_fin, 2, '0')  
//        and liqapo.id_tipo_doc = $id_tipo_doc
//        and liqapo.num_doc = $num_doc
//        
//    )tab
//    
//    group by 
//    tab.id_tipo_doc,
//    tab.num_doc,
//    tab.ID_PERIODO/*,
//    tab.TIPO_PLANILLA*/
//
//)tab
//group by 
//tab.id_tipo_doc,
//tab.num_doc
//EOD;

                        /**
                         * Se cambia la tabla de donde se obtiene la informacion de liquida_aporte por liquida_nomina - 20140717
                         * Se agregan valores de concepto de ajuste y reintegro - 20170113
                         * Se agregan valores de FSP de ajuste y reintegro, segun el retroactivo, se hace en la union - 20170113
                         * Se valida uninon ya que omitia registros iguales, se agrega id_liquida_nomina - 20180118
                         * Se agrega union para reintegro, ya que no tenia en cuenta cuando es por ajuste de nomina, solo relacion con el concepto original - 20190715
                         * val_rein en la primera union, se quita ya que en el 3 union esta tomando los reintegros - 20200115
                         * Incidente #37418, porcentaje is not null, en la consulta para los rein de retro se toma asi no tenga porcentaje, pero si tenga el concepto clase de fondo - 20240112
                         */
                        $sql = <<<EOD
select
tab.id_tipo_doc,
tab.num_doc,
sum(valor_pen_a + case when valor_pen_c > 0 then valor_pen_c else 0 end  ) as valor_pen,
sum(valor_fsp_a + case when valor_fsp_c > 0 then valor_fsp_c else 0 end) as valor_fsp,
sum(valor_sal_a + case when valor_sal_c > 0 then valor_sal_c else 0 end) as valor_sal,
sum(dias_sal) as dias_sal

from
(

    select
    tab.id_tipo_doc,
    tab.num_doc,
    tab.ID_PERIODO,
    /*
    count(tab.ID_PERIODO),
    tab.TIPO_PLANILLA,
    */
    nvl( sum( tab.aporte_func ) ,0) as total,
    nvl( sum( case when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'A' then tab.aporte_func + tab.val_ajus - val_rein else 0 end ) ,0) as valor_pen_a,
    nvl( sum(
    case when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
          when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'C' then tab.aporte_func 
          else 0 end 
    ) ,0) as valor_pen_c,
    
    nvl( sum( case when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'A' then tab.aporte_func + tab.val_ajus - val_rein else 0 end ) ,0) as valor_fsp_a,
    nvl( sum(
    case when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
          when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'C' then tab.aporte_func 
          else 0 end 
    ) ,0) as valor_fsp_c,
    
    nvl( sum( case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.aporte_func + tab.val_ajus - val_rein else 0 end ) ,0) as valor_sal_a,
    nvl( sum(
    case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
          when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'C' then tab.aporte_func 
          else 0 end 
    ) ,0) as valor_sal_c,
    
    nvl( sum( case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.num_dias else 0 end ) ,0) as dias_sal
    
    from
    (
      
        select
        liqapo.id_liquida_nomina,
        liqapo.id_tipo_doc,
        liqapo.num_doc,
        liqapo.ID_PERIODO,
        des.id_descuento_ss,
        liqapo.valor_liquidado as aporte_func,
        'A' as TIPO_PLANILLA,
        liqapo.num_dias
        /*
        nvl( sum( liqapo.aporte_func ) ,0) as total,
        nvl( sum( case when des.id_descuento_ss = 1 then liqapo.aporte_func else 0 end ) ,0) as valor_pen,
        nvl( sum( case when des.id_descuento_ss = 2 then liqapo.aporte_func else 0 end ) ,0) as valor_fsp,
        nvl( sum( case when des.id_descuento_ss = 3 then liqapo.aporte_func else 0 end ) ,0) as valor_sal,
        nvl( sum( case when des.id_descuento_ss = 3 then liqapo.num_dias else 0 end ) ,0) as dias_sal
        */
        ,nvl( (select sum(liq.valor_liquidado) from no_liquida_nomina liq 
              where liq.id_tipo_doc = liqapo.id_tipo_doc and liq.num_doc = liqapo.num_doc 
              and liq.id_periodo = liqapo.id_periodo and liq.id_concep_nomina = concep.id_concep_ajuste) ,0) as val_ajus
        ,nvl( (select sum(liq.valor_liquidado) from no_liquida_nomina liq 
              where liq.id_tipo_doc = liqapo.id_tipo_doc and liq.num_doc = liqapo.num_doc 
              and liq.id_periodo = liqapo.id_periodo and liq.id_concep_nomina = concep.id_concep_rein) ,0) * 0 as val_rein
                                
        from no_liquida_nomina liqapo
        
        join no_concep_nomina concep
        on liqapo.id_concep_nomina = concep.id_concep_nomina
        --and liqapo.id_clase_fondo = concep.id_clase_fondo
        
        join no_fondo_concepto foncon
        on foncon.id_concep_nomina = concep.id_concep_nomina
        --and foncon.id_mae_fondos = liqapo.id_mae_fondos
        
        join no_descuento_ss des
        on foncon.id_descuento_ss = des.id_descuento_ss
        
        join no_clase_fondo cla
        on  concep.id_clase_fondo = cla.id_clase_fondo
        
        join no_periodo_v per
        on per.id_periodo = liqapo.id_periodo
        
        where 
        per.id_anhos || lpad(per.id_meses, 2, '0') between  $vig_ini || lpad( $per_ini, 2, '0')  and $vig_fin || lpad( $per_fin, 2, '0')  
        and liqapo.id_tipo_doc = $id_tipo_doc
        and liqapo.num_doc = $num_doc
        
        union
        
        select
        liqapo.id_liquida_nomina,
        liqapo.id_tipo_doc,
        liqapo.num_doc,
        liqapo.ID_PERIODO,
        --des.id_descuento_ss,
        ( select foco.id_descuento_ss from no_fondo_concepto foco where foco.id_concep_nomina = (select max(con.id_concep_nomina) from no_concep_nomina con where con.id_concep_ajuste = liqapo.id_concep_nomina)) as id_descuento_ss,
        liqapo.valor_liquidado as aporte_func,
        'A' as TIPO_PLANILLA,
        0 as num_dias
        ,0 as val_ajus
        ,0 as val_rein
        
        from no_liquida_nomina liqapo
        
        left join no_concep_nomina concep
        on liqapo.id_concep_nomina = concep.id_concep_nomina
        --and liqapo.id_clase_fondo = concep.id_clase_fondo
        
        left join no_fondo_concepto foncon
        on foncon.id_concep_nomina = concep.id_concep_nomina
        --and foncon.id_mae_fondos = liqapo.id_mae_fondos
        
        left join no_descuento_ss des
        on foncon.id_descuento_ss = des.id_descuento_ss
        
        left join no_clase_fondo cla
        on  concep.id_clase_fondo = cla.id_clase_fondo
        
        join no_periodo_v per
        on per.id_periodo = liqapo.id_periodo
        
        where 
        per.id_anhos || lpad(per.id_meses, 2, '0') between  $vig_ini || lpad( $per_ini, 2, '0')  and $vig_fin || lpad( $per_fin, 2, '0')  
        and liqapo.id_tipo_doc = $id_tipo_doc
        and liqapo.num_doc = $num_doc
        
        --and liqapo.porcentaje is not null
        and ( liqapo.porcentaje is not null or concep.ID_CLASE_FONDO in (1,2) )
        and liqapo.id_concep_nomina not in (select fc.id_concep_nomina from no_fondo_concepto fc )
        
        union
        
        select
        liqapo.id_liquida_nomina,
        liqapo.id_tipo_doc,
        liqapo.num_doc,
        liqapo.ID_PERIODO,
        --des.id_descuento_ss,
        ( select foco.id_descuento_ss from no_fondo_concepto foco where foco.id_concep_nomina = (select max(con.id_concep_nomina) from no_concep_nomina con where con.id_concep_rein = liqapo.id_concep_nomina)) as id_descuento_ss,
        0 as aporte_func,
        'A' as TIPO_PLANILLA,
        0 as num_dias
        ,0 as val_ajus
        ,liqapo.valor_liquidado as val_rein
        
        from no_liquida_nomina liqapo
        
        left join no_concep_nomina concep
        on liqapo.id_concep_nomina = concep.id_concep_nomina
        --and liqapo.id_clase_fondo = concep.id_clase_fondo
        
        left join no_fondo_concepto foncon
        on foncon.id_concep_nomina = concep.id_concep_nomina
        --and foncon.id_mae_fondos = liqapo.id_mae_fondos
        
        left join no_descuento_ss des
        on foncon.id_descuento_ss = des.id_descuento_ss
        
        left join no_clase_fondo cla
        on  concep.id_clase_fondo = cla.id_clase_fondo
        
        join no_periodo_v per
        on per.id_periodo = liqapo.id_periodo
        
        where 
        per.id_anhos || lpad(per.id_meses, 2, '0') between  $vig_ini || lpad( $per_ini, 2, '0')  and $vig_fin || lpad( $per_fin, 2, '0')  
        and liqapo.id_tipo_doc = $id_tipo_doc
        and liqapo.num_doc = $num_doc
        
        --and liqapo.porcentaje is not null
        and ( liqapo.porcentaje is not null or concep.ID_CLASE_FONDO in (1,2) )
        and liqapo.id_concep_nomina not in (select fc.id_concep_nomina from no_fondo_concepto fc )
        
    )tab
    
    group by 
    tab.id_tipo_doc,
    tab.num_doc,
    tab.ID_PERIODO/*,
    tab.TIPO_PLANILLA*/

)tab
group by 
tab.id_tipo_doc,
tab.num_doc
EOD;
                        //Ejecutar SQL
                        $records_apo = CN_TABLE::executeSQL($sql);
                        if (count($records_apo) > 0) {
                            $apopen += $records_apo[0]['valor_pen'];
                            $apofsp += $records_apo[0]['valor_fsp'];
                        } else {
                            $apopen += 0;
                            $apofsp += 0;
                        }


                        /**
                         * Para CYC, Incidente #15733 - 20200117
                         * En el proceso de PORCENTAJE FIJO de retefuente procedimiento 2, que se ejecuta cada 6 meses, 
                         * para la entidad CYC, únicamente para ellos, se debe hacer que :
                         * - La sumatoria de aportes al sistema de SALUD, no sea el del año anterior, sino el mismo rango de PENSION.
                         * 
                          per.id_anhos = ($vig_fin-1)
                          --per.id_anhos = (select no_periodo_v.id_anhos - 1 from no_periodo_v where id_periodo = $id_periodo)
                          --per.id_anhos || lpad(per.id_meses, 2, '0') between $vig_ini || lpad( $per_ini, 2, '0') and $vig_fin || lpad( $per_fin, 2, '0')
                         */
                        $where_salud = "per.id_anhos = ($vig_fin-1)";
                        if ($entidadCliente == 4) {
                            $where_salud = "per.id_anhos || lpad(per.id_meses, 2, '0') between $vig_ini || lpad( $per_ini, 2, '0') and $vig_fin || lpad( $per_fin, 2, '0')";
                        }

                        /*
                         * Para calcular salud obligatoria y dias para el año anterior
                         * Tomar rango de meses del filtro - 20130705 NO se utilizo
                         * --per.id_anhos = (select no_periodo_v.id_anhos - 1 from no_periodo_v where id_periodo = $id_periodo)
                         * Para calcular pension y fondo solidaridad para el año anterior - 20130705 
                         * Se debe tener encuenta valores de retroactivo en el calculo - 20140106
                         * Segun revision la pension y fsp se calcula del rango de periodos seleccionados - 20140107
                         * Se agregan valores de concepto de ajuste y reintegro - 20170113 
                         * Incidente #8056,Para procesar el acumulado de APORTE OBLIGATORIO DE SALUD, se debe tomar del año anterior al año de corte, 
                         * que en este caso es el año anterior al campo "Vigencia Final Para el calculo que se esta aplicando con corte a Noviembre de 2017, 
                         * se debe tomar el acumulado de la vigencia 2016. - 20180118
                         */
                        //sql
                        $sql = <<<EOD
select
tab.id_tipo_doc,
tab.num_doc,
sum(valor_pen_a + case when valor_pen_c > 0 then valor_pen_c else 0 end  ) as valor_pen,
sum(valor_fsp_a + case when valor_fsp_c > 0 then valor_fsp_c else 0 end) as valor_fsp,
sum(valor_sal_a + case when valor_sal_c > 0 then valor_sal_c else 0 end) as valor_sal,
sum(dias_sal) as dias_sal

from
(

    select
    tab.id_tipo_doc,
    tab.num_doc,
    tab.ID_PERIODO,
    /*
    count(tab.ID_PERIODO),
    tab.TIPO_PLANILLA,
    */
    nvl( sum( tab.aporte_func ) ,0) as total,
    nvl( sum( case when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'A' then tab.aporte_func + tab.val_ajus - val_rein else 0 end ) ,0) as valor_pen_a,
    nvl( sum(
    case when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
          when tab.id_descuento_ss = 1 and tab.tipo_planilla = 'C' then tab.aporte_func 
          else 0 end 
    ) ,0) as valor_pen_c,
    
    nvl( sum( case when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'A' then tab.aporte_func + tab.val_ajus - val_rein else 0 end ) ,0) as valor_fsp_a,
    nvl( sum(
    case when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
          when tab.id_descuento_ss = 2 and tab.tipo_planilla = 'C' then tab.aporte_func 
          else 0 end 
    ) ,0) as valor_fsp_c,
    
    nvl( sum( case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.aporte_func + tab.val_ajus - val_rein else 0 end ) ,0) as valor_sal_a,
    nvl( sum(
    case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.aporte_func * (-1)
          when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'C' then tab.aporte_func 
          else 0 end 
    ) ,0) as valor_sal_c,
    
    nvl( sum( case when tab.id_descuento_ss = 3 and tab.tipo_planilla = 'A' then tab.num_dias else 0 end ) ,0) as dias_sal
    
    from
    (
      
        select
        liqapo.id_tipo_doc,
        liqapo.num_doc,
        liqapo.ID_PERIODO,
        des.id_descuento_ss,
        liqapo.aporte_func,
        liqapo.TIPO_PLANILLA,
        liqapo.num_dias
        /*
        nvl( sum( liqapo.aporte_func ) ,0) as total,
        nvl( sum( case when des.id_descuento_ss = 1 then liqapo.aporte_func else 0 end ) ,0) as valor_pen,
        nvl( sum( case when des.id_descuento_ss = 2 then liqapo.aporte_func else 0 end ) ,0) as valor_fsp,
        nvl( sum( case when des.id_descuento_ss = 3 then liqapo.aporte_func else 0 end ) ,0) as valor_sal,
        nvl( sum( case when des.id_descuento_ss = 3 then liqapo.num_dias else 0 end ) ,0) as dias_sal
        */
        ,nvl( (select sum(liq.valor_liquidado) from no_liquida_nomina liq 
              where liq.id_tipo_doc = liqapo.id_tipo_doc and liq.num_doc = liqapo.num_doc 
              and liq.id_periodo = liqapo.id_periodo and liq.id_concep_nomina = concep.id_concep_ajuste) ,0) as val_ajus
        ,nvl( (select sum(liq.valor_liquidado) from no_liquida_nomina liq 
              where liq.id_tipo_doc = liqapo.id_tipo_doc and liq.num_doc = liqapo.num_doc 
              and liq.id_periodo = liqapo.id_periodo and liq.id_concep_nomina = concep.id_concep_rein) ,0) as val_rein
                                
        from no_liquida_aporte liqapo
        
        join no_concep_nomina concep
        on liqapo.id_concep_nomina = concep.id_concep_nomina
        and liqapo.id_clase_fondo = concep.id_clase_fondo
        
        join no_fondo_concepto foncon
        on foncon.id_concep_nomina = concep.id_concep_nomina
        and foncon.id_mae_fondos = liqapo.id_mae_fondos
        
        join no_descuento_ss des
        on foncon.id_descuento_ss = des.id_descuento_ss
        
        join no_clase_fondo cla
        on  concep.id_clase_fondo = cla.id_clase_fondo
        
        join no_periodo_v per
        on per.id_periodo = liqapo.id_periodo
        
        where 
        $where_salud
        and liqapo.id_tipo_doc = $id_tipo_doc
        and liqapo.num_doc = $num_doc
        
    )tab
    
    group by 
    tab.id_tipo_doc,
    tab.num_doc,
    tab.ID_PERIODO/*,
    tab.TIPO_PLANILLA*/

)tab
group by 
tab.id_tipo_doc,
tab.num_doc
EOD;
                        //Ejecutar SQL
                        $records_apo = CN_TABLE::executeSQL($sql);
                        if (count($records_apo) > 0) {
                            $aposal_obl += $records_apo[0]['valor_sal'];
                            $diasal_obl += $records_apo[0]['dias_sal'];
                        } else {
                            $aposal_obl += 0;
                            $diasal_obl += 0;
                        }
//                        if (count($records_apo) > 0) {
//                            $apopen += $records_apo[0]['valor_pen'];
//                            $apofsp += $records_apo[0]['valor_fsp'];
//                        } else {
//                            $apopen += 0;
//                            $apofsp += 0;
//                        }
//                    die();
                        $i++;


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

                            $this->logMessage("[Informe Base Calculo ReteFuente] El valor liquidado es: " . $valor_liquidado);


                            /**
                             * Proceso de calculo retenfuente
                             */
                            //sql para cant concepto nomina
                            //7002 - id 443 - INTERESES DE VIVIENDA
                            $sql = <<<EOD
select * from no_concep_nomina
where id_concep_nomina = 443 
EOD;
                            //Ejecutar SQL
                            $records_con = CN_TABLE::executeSQL($sql);
                            if (count($records_con) > 0) {
                                $max_intere = $uvt * $records_con[0]['cant_uvt'] * 12; //uvts
                            } else {
                                $max_intere = $uvt * 100 * 12; //uvts
                            }

                            //sql para cant concepto nomina
                            //7003 - id 444 - CERTIFICADOS DE SALUD, EDUCACI
                            $sql = <<<EOD
select * from no_concep_nomina
where id_concep_nomina = 444 
EOD;
                            //Ejecutar SQL
                            $records_con = CN_TABLE::executeSQL($sql);
                            if (count($records_con) > 0) {
                                $top_edu = $uvt_ant * $records_con[0]['cant_uvt']; //uvts
                            } else {
                                $top_edu = $uvt_ant * 4600; //uvtant
                            }

                            //sql para cant concepto nomina
                            //7006 - id 445 - CERTIFICACION DEPENDIENTES
                            $sql = <<<EOD
select 
meses,
round( case when meses > 0 then valor_descuento else 0 end ,0)  as valor_descuento
from no_certi_retefuente
where id_periodo = $id_periodo
and id_tipo_doc = $id_tipo_doc and num_doc = '$num_doc'
and id_concep_nomina = 445 
EOD;
                            //Ejecutar SQL
                            $records_certi = CN_TABLE::executeSQL($sql);
                            if (count($records_certi) > 0) {
                                $meses_dep = $records_certi[0]['meses'];
                                $valor_dep = $records_certi[0]['valor_descuento'];
                                $tag_dep = true; //valida que tenga certificado dependiente en el periodo
                            } else {
                                $meses_dep = 0;
                                $valor_dep = 0;
                                $tag_dep = false; //valida que tenga certificado dependiente en el periodo
                            }

                            //sql para valor certif - des_cerdep
                            //7004 - id 545 - CERTIFICACION DEPENDIENTES MENSUAL
                            $sql = <<<EOD
select NVL(SUM(LIQNOM.VALOR),0) as valor_descuento, count(*) as cant_mes  
    from no_concepto_periodo LIQNOM  
join NO_PERIODO PER on PER.ID_PERIODO = LIQNOM.PERIODO where  1 = 1 and PER.ID_ANHOS || LPAD(PER.ID_MESES, 2, '0') 
between  $vig_ini || LPAD( $per_ini, 2, '0')  and $vig_fin || LPAD( $per_fin, 2, '0')  
and liqnom.num_doc = $num_doc  and liqnom.id_tipo_doc = $id_tipo_doc  
    and liqnom.id_concep_nomina = 545
EOD;
                            //Ejecutar SQL
                            $records_certif = CN_TABLE::executeSQL($sql);
                            $cant_mes = 0;
                            if (count($records_certif) > 0) {
                                $cer_cerdep = $records_certif[0]['valor_descuento'] + $valor_dep;
                                $cant_mes = $records_certif[0]['cant_mes'];
                            }
                            /**
                             * COLCIENCIAS: Se deja la cantidad de meses en 12 segun la resolucion y conferencia con Olga de colciencias - 20140717
                             */
                            $cant_mes = 12;
                            $meses_dep = 0;


                            //sql para valor certif - des_cerdep
                            //7004 - id 545 - CERTIFICACION DEPENDIENTES MENSUAL
                            $sql = <<<EOD
select * from no_concep_nomina
where id_concep_nomina = 545 
EOD;
                            //Ejecutar SQL
                            $records_con = CN_TABLE::executeSQL($sql);
                            if (count($records_con) > 0) {
                                $this->logMessage("[Informe Base Calculo ReteFuente] Cant uvts: " . $uvt);
                                $top_cerdep = $uvt * $records_con[0]['cant_uvt'] * ($cant_mes + $meses_dep); //uvts
                            } else {
                                $top_cerdep = $uvt * 32 * ($cant_mes + $meses_dep); //uvtant
                            }

                            $this->logMessage("[Informe Base Calculo ReteFuente] El valor top_cerdep es: " . $top_cerdep);

                            /*
                             * 10 % del $valor_liquidado
                             * que no supere 32 UVT
                             */
                            //valida que tenga certificado dependiente en el periodo
                            if ($tag_dep) {
                                /*
                                 * INCI: Se hace una modificacion en el calculo del valor que se debe colocar en la columna CER_CERDEP asi:
                                 * si tiene la certificacion   concepto 7006,  ID 445,       esta casilla se llena con   (tot_dev*10/100)
                                 * se coloca el tope  y se establece que valor debe ir en DES_CERDEP - 20130722
                                 */
                                $cer_cerdep = ($valor_liquidado * 10) / 100;
                                if ($cer_cerdep > 0) {
                                    $max_cerdep = ($valor_liquidado * 10) / 100;
                                    //valida 10 porciento y el tope uvt
                                    if ($max_cerdep > $top_cerdep) {
                                        if ($cer_cerdep > $top_cerdep) {
                                            $des_cerdep = $top_cerdep;
                                        } else {
                                            $des_cerdep = $cer_cerdep;
                                        }
                                        $max_cerdep = $top_cerdep;
                                    } else {
                                        if ($cer_cerdep > $max_cerdep) {
                                            $des_cerdep = $max_cerdep;
                                        } else {
                                            $des_cerdep = $cer_cerdep;
                                        }
                                        //INCI modificacion en el calculo del valor...: 20130722 - Para todos 20140717
                                        $max_cerdep = $top_cerdep;
                                    }
                                }
                            }

//                            if ($cer_cerdep > 0) {
//                                $max_cerdep = ($valor_liquidado * 10) / 100;
//                                //valida 10 porciento y el tope uvt
//                                if ($max_cerdep > $top_cerdep) {
//                                    $des_cerdep = $top_cerdep;
//                                    $max_cerdep = $top_cerdep;
//                                } else {
//                                    $des_cerdep = $max_cerdep;
//                                }
//                            }
                            //Segun articulo 386 se debe tomar todo el valor, no por los dias - 20130708
                            //$des_salobl = ( $diasal_obl > 0 && $aposal_obl > 0 ) ? ($aposal_obl / $diasal_obl) * 30 : 0;
                            $des_salobl = ( $diasal_obl > 0 && $aposal_obl > 0 ) ? ($aposal_obl) : 0;


                            /*
                             * Valores de la tabla
                             * 7002 - id 443 - INTERESES DE VIVIENDA
                             */
                            $sql = <<<EOD
select 
round( case when meses = 0 then valor_descuento else valor_descuento/meses end ,0)  as valor_descuento
from no_certi_retefuente
where id_periodo = $id_periodo
and id_tipo_doc = $id_tipo_doc and num_doc = '$num_doc'
and id_concep_nomina = 443 
EOD;
                            //Ejecutar SQL
                            $records_certi = CN_TABLE::executeSQL($sql);
                            if (count($records_certi) > 0) {
                                $cer_intere = $records_certi[0]['valor_descuento'];
                            } else {
                                $cer_intere = 0;
                            }
                            $this->logMessage("7002 - valor_descuento - " . $cer_intere);

                            $records_certi = array();

                            /*
                             * Valores de la tabla
                             * 7003 - id 444 - CERTIFICADOS DE SALUD, EDUCACI
                             */
                            $sql = <<<EOD
select 
round( case when meses = 0 then valor_descuento else valor_descuento/meses end ,0)  as valor_descuento    
from no_certi_retefuente
where id_periodo = $id_periodo
and id_tipo_doc = $id_tipo_doc and num_doc = '$num_doc'
and id_concep_nomina = 444 
EOD;
                            //Ejecutar SQL
                            $records_certi = CN_TABLE::executeSQL($sql);
                            if (count($records_certi) > 0) {
                                $cer_saledu = $records_certi[0]['valor_descuento'];
                            } else {
                                $cer_saledu = 0;
                            }
                            $this->logMessage("7003 - valor_descuento - " . $cer_saledu);

                            $max_saledu = $uvt * 16 * 12;

                            //valor $des_intere
                            //Se agrega validacion por ($cer_intere < $max_intere) - 20130709
                            if ($cer_intere < $max_intere && $cer_intere > $max_saledu) {
                                $des_intere = $cer_intere;
                            } elseif ($cer_intere < $max_intere && $cer_intere <= $max_saledu && $cer_saledu == 0) {
                                $des_intere = $cer_intere;
                            } elseif ($cer_intere > $cer_saledu && $cer_intere < $max_intere) {
                                $des_intere = $cer_intere;
                            } elseif ($cer_intere < $max_intere) {
                                $des_intere = $cer_intere;
                            } else {
                                $des_intere = $max_intere;
                            }

                            //valor $des_saledu
                            //Se agrega validacion por ($cer_saledu < $max_saledu) - 20130709
                            if ($max_saledu >= $cer_saledu && $des_intere == 0 && $subtot1 < $top_edu) {
                                $des_saledu = $cer_saledu;
                            } elseif ($max_saledu < $cer_saledu && $des_intere == 0 && $subtot1 < $top_edu) {
                                $des_saledu = $max_saledu;
                            } elseif ($cer_saledu < $max_saledu) {
                                $des_saledu = $cer_saledu;
                            } else {
                                $des_saledu = $max_saledu;
                            }

                            /**
                             * Tope maximo de uvt para voluntarios - 20230117::LAVILA
                             */
                            $max_apovol = $uvt * 3800;
                            if ($apovol > $max_apovol) {
                                $apovol = $max_apovol;
                            }

                            /**
                             * Segun articulo 386 se restan los valores al subtotal1 - 20130708
                             * Cambios de calculo retencion - procedimiento 2 - 20170712
                             */
//                            //$subtot1 = $valor_liquidado - $apopen - $apofsp - $apovol - $des_cerdep;
//                            $subtot1 = $valor_liquidado - $apopen - $apofsp - $apovol - $des_cerdep - $des_saledu - $des_intere - $des_salobl;
//
//                            $c25_exec = $subtot1 * 25 / 100;
//                            $c25_exec_tope = $uvt * 240 * 12;
//                            if ($c25_exec > $c25_exec_tope) {
//                                $c25_exec = $c25_exec_tope;
//                            }
//
//                            $subtot2 = $subtot1 - $c25_exec;
//                            $dividido13 = ( $dias_liq >= 360 ) ? $subtot2 / 13 : $subtot2 / ($dias_liq / 30);
//
//                            //Segun articulo 386 no se restan los valores al dividido13 - 20130708
//                            //$ingr_prome = $dividido13 - $des_saledu - $des_intere - $des_salobl;
//                            $ingr_prome = $dividido13;
//                            $prom_uvts = $ingr_prome / $uvt;

                            $subtot1 = $valor_liquidado - $apopen - $apofsp - $des_salobl;

                            $subtot2 = $subtot1 - $des_saledu - $des_intere - $des_cerdep - $apovol;

                            $c25_exec = $subtot2 * 25 / 100;
                            /*
                             * Incidente #35851 - 20230623::LAVILA
                              Columna W - C25_EXEC
                              Debe validar un tope maximo de 790 UVTS, si el valor supera dejar hasta maximo 790 UVTS.
                             */
                            //$c25_exec_tope = $uvt * 240 * 12;
                            $c25_exec_tope = $uvt * 790;
                            if ($c25_exec > $c25_exec_tope) {
                                $c25_exec = $c25_exec_tope;
                            }

                            $sum_rent_deduc = $des_saledu + $des_intere + $des_cerdep + $apovol + $c25_exec;

                            $c40_exec = $subtot1 * 40 / 100;
                            /*
                             * Incidente #35851 - 20230623::LAVILA
                              Columna Y - C40_EXEC
                              Debe validar un tope maximo de 1340 UVTS, si el valor supera dejar hasta maximo 1340 UVTS.
                             */
                            $c40_exec_tope = $uvt * 1340;
                            if ($c40_exec > $c40_exec_tope) {
                                $c40_exec = $c40_exec_tope;
                            }

                            $adic_subtot3 = ( $sum_rent_deduc >= $c40_exec ) ? $c40_exec : $sum_rent_deduc;

                            $subtot3 = $subtot1 - $adic_subtot3;

                            //Validacion de dias = 0, para que no calcule retencion y no genere errores - 20250110::LAVILA
                            if ($dias_liq != 0) {
                                $dividido13 = ( $dias_liq >= 360 ) ? $subtot3 / 13 : $subtot3 / ($dias_liq / 30);
                            }else{
                                $this->logMessage("[Informe Base Calculo ReteFuente] El dias_liq($dias_liq) es cero.");
                                $dividido13 = 0;
                            }

                            //Segun articulo 386 no se restan los valores al dividido13 - 20130708
                            //$ingr_prome = $dividido13 - $des_saledu - $des_intere - $des_salobl;
                            $ingr_prome = $dividido13;
                            $prom_uvts = $ingr_prome / $uvt;

                            //Datos quemados, segu tabla ts_reten383 - 20190717
                            //Validacion uvt
                            if ($prom_uvts > 95 && $prom_uvts <= 150) {
                                $tar_margi = 19;
                            } elseif ($prom_uvts > 150 && $prom_uvts <= 360) {
                                $tar_margi = 28;
                            } elseif ($prom_uvts > 360 && $prom_uvts <= 640) {
                                $tar_margi = 33;
                            } elseif ($prom_uvts > 640 && $prom_uvts <= 945) {
                                $tar_margi = 35;
                            } elseif ($prom_uvts > 945 && $prom_uvts <= 2300) {
                                $tar_margi = 37;
                            } elseif ($prom_uvts > 2300) {
                                $tar_margi = 39;
                            } else {
                                $tar_margi = 0;
                            }

                            if ($tar_margi == 19) {
                                $men_prouvt = 95;
                                $maspuntos = 0;
                            } elseif ($tar_margi == 28) {
                                $men_prouvt = 150;
                                $maspuntos = 10;
                            } elseif ($tar_margi == 33) {
                                $men_prouvt = 360;
                                $maspuntos = 69;
                            } elseif ($tar_margi == 35) {
                                $men_prouvt = 640;
                                $maspuntos = 162;
                            } elseif ($tar_margi == 37) {
                                $men_prouvt = 945;
                                $maspuntos = 268;
                            } elseif ($tar_margi == 39) {
                                $men_prouvt = 2300;
                                $maspuntos = 770;
                            } else {
                                $men_prouvt = 0;
                                $maspuntos = 0;
                            }

                            if ($tar_margi == 19) {
                                $reten_uvts = (($prom_uvts - $men_prouvt) * ($tar_margi / 100));
                            } elseif ($tar_margi == 28) {
                                $reten_uvts = (($prom_uvts - $men_prouvt) * ($tar_margi / 100) + 10);
                            } elseif ($tar_margi == 33) {
                                $reten_uvts = (($prom_uvts - $men_prouvt) * ($tar_margi / 100) + 69);
                            } elseif ($tar_margi == 35) {
                                $reten_uvts = (($prom_uvts - $men_prouvt) * ($tar_margi / 100) + 162);
                            } elseif ($tar_margi == 37) {
                                $reten_uvts = (($prom_uvts - $men_prouvt) * ($tar_margi / 100) + 268);
                            } elseif ($tar_margi == 39) {
                                $reten_uvts = (($prom_uvts - $men_prouvt) * ($tar_margi / 100) + 770);
                            } else {
                                $reten_uvts = 0;
                            }

                            $reten = ($reten_uvts > 0) ? ($reten_uvts / $prom_uvts) * 100 : 0;

                            //Obtener id de retefuente
                            //Sql
                            $sql = <<<EOD
select nvl(tab0.porcentaje, 0) as porcentaje from no_concepto_func tab0
where tab0.id_concep_nomina = (select no_param_concep.id_concep_rete 
from no_param_concep where no_param_concep.id_param_concep = 1) 
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc 
EOD;
                            //Ejecutar SQL
                            $record_porcentaje = CN_TABLE::executeSQL($sql);
                            if (count($record_porcentaje) > 0) {
                                $porcentaje = $record_porcentaje[0]['porcentaje'];
                            } else {
                                $porcentaje = 0;
                            }

                            $reten_ante = $porcentaje;


                            /*
                             * Crear nueva liquidación
                             * 
                             * Asignar valores encontrados en persona
                             */
                            //insert into no_cal_retefuente (id_calc_retefuente,id_periodo,id_tipo_doc,num_doc,fecha_ingreso,diastot,totdev,apopen,apofsp,apovol,subtot1,
                            //c25_exec,subtot2,dividido13,aposal_obl,diasal_obl,des_salobl,cer_saledu,max_saledu,des_saledu,cer_intere,max_intere,des_intere,ingr_prome,
                            //prom_uvts,tar_margi,men_prouvt,maspuntos,reten_uvts,reten,reten_ante) 
                            //values ('4','47','1','10251335',to_date('07/05/12','DD/MM/RR'),'336','50339774',
                            //'1412355','345400','0','48582019','12145505','36436514','3253260','1496951','360',
                            //'124746','0','487989','0','778814','2604900','778814','2349700','90',
                            //'0','0','0','0','0','0');
                            //
                            //Se crean campos nuevos usuario,fecha_log, para saber quien realizo el ultimo calculo  - 20180117
                            //Sql
                            $sql = <<<EOD
insert into no_cal_retefuente (id_calc_retefuente,id_periodo,id_tipo_doc,num_doc,fecha_ingreso,diastot,
    totdev,apopen,apofsp,apovol,subtot1,
    c25_exec,subtot2,dividido13,aposal_obl,diasal_obl,des_salobl,cer_saledu,max_saledu,des_saledu,cer_intere,
    max_intere,des_intere,ingr_prome,
    prom_uvts,tar_margi,men_prouvt,maspuntos,reten_uvts,reten,reten_ante
        ,cer_cerdep,max_cerdep,des_cerdep
            ,sum_rent_deduc,c40_exec,adic_subtot3,subtot3,
                usuario,fecha_log) 
values (null,$id_periodo,$id_tipo_doc,$num_doc,to_date('$fecha_ingreso','yyyy-mm-dd'), $dias_liq,
    $valor_liquidado, $apopen, $apofsp, $apovol, $subtot1,
    $c25_exec, $subtot2, $dividido13, $aposal_obl, $diasal_obl,
    $des_salobl, $cer_saledu, $max_saledu, $des_saledu, $cer_intere,
    $max_intere, $des_intere, $ingr_prome, $prom_uvts, $tar_margi,
    $men_prouvt, $maspuntos, $reten_uvts, $reten, $reten_ante, 
        $cer_cerdep, $max_cerdep, $des_cerdep,
            $sum_rent_deduc, $c40_exec, $adic_subtot3, $subtot3    ,
                '$username',sysdate )   
EOD;
                            //Ejecutar SQL
                            CN_TABLE::executeSQL($sql);
                        } else {

                            $this->logMessage("[Informe Base Calculo ReteFuente] El valor_liquidado es menor a cero.");
                        }
                    }
                    /*
                     * Memcache al 100 porciento
                     */
                    MemcacheHandler::getInstance()->set($progress_key, 100);

                    /*
                     * COMMIT DE TODAS LAS TRANSACCIONES
                     */
                    $this->conn->commit();
                    $this->status = 0;
                    $this->list_data = array();
                    $this->logMessage("[Informe Base Calculo ReteFuente] Calcular ReteFuente Terminado.");
                } else {
                    MemcacheHandler::getInstance()->set($progress_key, 100);

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

                    /*
                     * Mensaje de error
                     */
                    $mensajeError = "No hay funcionarios para calcular retefuente.";

                    $this->status = 1;
                    $this->list_data = array();
                    $this->mensajeError = $mensajeError;
                    $this->logMessage("[Informe Base Calculo ReteFuente] " . $mensajeError);
                }
            } else {
                MemcacheHandler::getInstance()->set($progress_key, 100);

                /**
                 * ROLLBACK DE TODAS LAS TRANSACCIONES EN CASO DE QUE OCURRA ALGUN ERROR
                 */
                $this->conn->rollback();

                /*
                 * Mensaje de error
                 */
                $mensajeError = "No hay valores para UVT, confirmar registros del año actual y anterior.";

                $this->status = 1;
                $this->list_data = array();
                $this->mensajeError = $mensajeError;
                $this->logMessage("[Informe Base Calculo ReteFuente] " . $mensajeError);
            }
        } catch (Exception $e) {
            MemcacheHandler::getInstance()->set($progress_key, 100);

            /**
             * ROLLBACK DE TODAS LAS TRANSACCIONES EN CASO DE QUE OCURRA ALGUN ERROR
             */
            $this->conn->rollback();

            /**
             * Respuesta del servicio
             */
            $this->status = 1;
            $this->mensajeError = "[Informe Base Calculo ReteFuente] Ocurrio un error: " . $e->getMessage();
            $this->list_data = array();
            $this->logMessage("[Informe Base Calculo ReteFuente] ERROR!");
            $this->logMessage($e->getMessage());
        }
    }

    /**
     * Actualizar ReteFuente
     *
     * @param sfRequest $request A request object
     */
    public function executeUpdate(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");

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

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

        try {

            /**
             * Variables de filtro
             */
            //Rango fecha
            $vig_ini = $request['vig_ini'];
            $vig_fin = $request['vig_fin'];
            $per_ini = $request['per_ini'];
            $per_fin = $request['per_fin'];

            //id_periodo
            $id_periodo = $request['id_periodo_filtro'];
            $progress_key = $request['progress_key'] . $request['username'];

            //id_agrup_concepto
            $id_agrup_dev = $request['id_agrup_dev'];
            $id_agrup_apovol = $request['id_agrup_apovol'];

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

            /**
             * Actualizar retefuente de funcionarios
             */
            //Obtener id de retefuente
            //Sql
            $sql = <<<EOD
select * from no_param_concep 
EOD;
            //Ejecutar SQL
            $record_param = CN_TABLE::executeSQL($sql);
            $id_concep_rete = $record_param[0]['id_concep_rete'];

            /*
             * Obtener registros para actualizar
             */
            //Sql
            $sql = <<<EOD
select
case when nom.estado = 0 and nom.fecha_termina <= per.fecha_ini then nom.estado else 1 end as estado,
per.id_anhos,
per.id_meses,
to_date('01/'||per.id_meses||'/'||per.id_anhos ,'dd/mm/yyyy') as fecha_ini,
trunc(last_day( TO_DATE( per.id_meses||'/'||per.id_anhos ,'mm/yyyy') )) as fecha_fin,
tab0.* 
from no_cal_retefuente tab0

join no_periodo_v per
on tab0.id_periodo = per.id_periodo

join no_nombramiento_v nom
on tab0.num_doc = nom.num_doc
and tab0.id_tipo_doc = nom.id_tipo_doc 

WHERE tab0.id_periodo = $id_periodo
$whereFuncionarioNumDoc $whereFuncionarioTipoDoc 
EOD;
            //Ejecutar SQL
            $records = CN_TABLE::executeSQL($sql);

            //validar registros de funcionarios
            if (count($records) > 0) {

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

                // Antes de inicar el proceso largo
                $brecha = 1;
                if ($nom_conceptos_a_procesar > 100)
                    $brecha = $nom_conceptos_a_procesar - (0.99 * $nom_conceptos_a_procesar);
                $this->logMessage("[Informe Base Calculo ReteFuente] nom_conceptos_a_procesar: " . $nom_conceptos_a_procesar);

                foreach ($records as $record) {

                    // Memcache - Guardar un valor en el proceso largo
                    if ($i % $brecha == 0) {
                        MemcacheHandler::getInstance()->set($progress_key, round(($i / $nom_conceptos_a_procesar) * 100, 0));
                    }
                    /*
                     * Datos por record
                     */
                    $estado = $record['estado'];
                    $num_doc = $record['num_doc'];
                    $id_tipo_doc = $record['id_tipo_doc'];
                    $reten = $record['reten'];
                    $id_anhos = $record['id_anhos'];
                    $id_meses = $record['id_meses'];
                    $fecha_ini = $record['fecha_ini'];
                    $fecha_fin = $record['fecha_fin'];

                    $this->logMessage("[Informe Base Calculo ReteFuente] Existen calcular retefuente. NumDoc: " . $num_doc);


                    /**
                     * Crear, actualizar o eliminar registro NO_CONCEPTO_FUNC y NO_CONCEPTO_PERIODO
                     * Otros conceptos 7000 -> id-441 y 7001 -> id-442
                     */
                    /*
                     * NO_CONCEPTO_FUNC
                     * Se adiciona si esta activo el concepto - 20160914
                     */
                    //Sql
                    $sql = <<<EOD
select tab0.* from no_concepto_func tab0
where tab0.id_concep_nomina = $id_concep_rete
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc
and tab0.estado = 1 
EOD;
                    //Ejecutar SQL
                    $record_concep_func = CN_TABLE::executeSQL($sql);
                    if (count($record_concep_func) > 0) {

                        //Si la retefuente es mayor a cero - 20140721
                        if ($reten > 0) {
                            $sql = <<<EOD
update no_concepto_func tab0 set porcentaje = $reten, fecha_desde=to_date('$fecha_ini','yyyy-mm-dd')
where tab0.id_concep_nomina = $id_concep_rete
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc 
EOD;
                            //Ejecutar SQL
                            CN_TABLE::executeSQL($sql);
                        } else {
                            $sql = <<<EOD
update no_concepto_func tab0 set estado = 0, actual = 0, fecha_hasta=to_date('$fecha_ini','yyyy-mm-dd')-1
where tab0.id_concep_nomina = $id_concep_rete
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc 
EOD;
                            //Ejecutar SQL
                            CN_TABLE::executeSQL($sql);
                        }
                    } else {

                        //Si la retefuente es mayor a cero - 20140721
                        if ($reten > 0) {

                            //insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
                            //id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
                            //values ('803','1','1015408219','208',null,'1','1','1',
                            //to_date('03/12/12','DD/MM/RR'),null);
                            //Sql
                            $sql = <<<EOD
insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
values (null,$id_tipo_doc,'$num_doc',$id_concep_rete,null,$reten,1,1,
to_date('$fecha_ini','yyyy-mm-dd'),null)  
EOD;
                            //Ejecutar SQL
                            CN_TABLE::executeSQL($sql);
                        }
                    }

                    /*
                     * NO_CONCEPTO_PERIODO
                     */
                    //Sql
                    $sql = <<<EOD
select tab0.* from no_concepto_periodo tab0
where tab0.id_concep_nomina = $id_concep_rete
and tab0.periodo = $id_periodo     
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc  
EOD;
                    //Ejecutar SQL
                    $record_concep_per = CN_TABLE::executeSQL($sql);
                    if (count($record_concep_per) > 0) {
                        $sql = <<<EOD
update no_concepto_periodo tab0 set porcentaje = $reten 
where tab0.id_concep_nomina = $id_concep_rete
and tab0.periodo = $id_periodo     
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc  
EOD;
                        //Ejecutar SQL
                        CN_TABLE::executeSQL($sql);
                    } else {

                        /*
                         * Si la retefuente es mayor a cero - 20140721
                         * Validar estado del tercero - 20230119::LAVILA
                         */
                        if ($reten > 0 && $estado != 0) {
                            //insert into no_concepto_periodo (id_concepto_periodo,id_anhos,id_meses,
                            //periodo,id_tipo_doc,num_doc,id_concep_nomina,fecha_desde,fecha_hasta,
                            //valor,porcentaje,num_dias) 
                            //values ('240','2012','11','1','1','1015408219','1',
                            //to_date('03/12/12','DD/MM/RR'),to_date('31/12/12','DD/MM/RR'),
                            //'1473178',null,'30');
                            //Sql
                            $sql = <<<EOD
insert into no_concepto_periodo (id_concepto_periodo,id_anhos,id_meses,
periodo,id_tipo_doc,num_doc,id_concep_nomina,fecha_desde,fecha_hasta,
valor,porcentaje,num_dias) 
values (null,$id_anhos,$id_meses,$id_periodo,$id_tipo_doc,'$num_doc',$id_concep_rete,
to_date('$fecha_ini','yyyy-mm-dd'),to_date('$fecha_fin','yyyy-mm-dd'),
null,$reten,30)   
EOD;
                            //Ejecutar SQL
                            CN_TABLE::executeSQL($sql);
                        }
                    }

                    $i++;



                    //No se actualiza el valor de otros conceptos - 20130709
                    /**
                     * Actualizar
                     * Otros conceptos 7000 -> id-441 y 7001 -> id-442
                     * Certif Dependientes - 7004 - 545
                     */
//                    $id_concep = 441;
//                    $valor = $record['des_saledu'] + $record['des_intere'];
//                    /*
//                     * NO_CONCEPTO_FUNC 7000 -> id-441
//                     */
//                    //Sql
//                    $sql = <<<EOD
//select tab0.* from no_concepto_func tab0
//where tab0.id_concep_nomina = $id_concep
//and tab0.id_tipo_doc = $id_tipo_doc
//and tab0.num_doc = $num_doc  
//EOD;
//                    //Ejecutar SQL
//                    $record_concep_func = CN_TABLE::executeSQL($sql);
//                    if (count($record_concep_func) > 0) {
//                        $sql = <<<EOD
//update no_concepto_func tab0 set valor = $valor, fecha_desde=to_date('$fecha_ini','yyyy-mm-dd')
//where tab0.id_concep_nomina = $id_concep
//and tab0.id_tipo_doc = $id_tipo_doc
//and tab0.num_doc = $num_doc 
//EOD;
//                        //Ejecutar SQL
//                        CN_TABLE::executeSQL($sql);
//                    } else {
//                        //insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
//                        //id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
//                        //values ('803','1','1015408219','208',null,'1','1','1',
//                        //to_date('03/12/12','DD/MM/RR'),null);
//                        //Sql
//                        $sql = <<<EOD
//insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
//id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
//values (null,$id_tipo_doc,'$num_doc',$id_concep,$valor,null,1,1,
//to_date('$fecha_ini','yyyy-mm-dd'),null)  
//EOD;
//                        //Ejecutar SQL
//                        CN_TABLE::executeSQL($sql);
//                    }
//
//                    /*
//                     * NO_CONCEPTO_PERIODO 7000 -> id-441
//                     */
//                    //Sql
//                    $sql = <<<EOD
//select tab0.* from no_concepto_periodo tab0
//where tab0.id_concep_nomina = $id_concep
//and tab0.periodo = $id_periodo     
//and tab0.id_tipo_doc = $id_tipo_doc
//and tab0.num_doc = $num_doc  
//EOD;
//                    //Ejecutar SQL
//                    $record_concep_per = CN_TABLE::executeSQL($sql);
//                    if (count($record_concep_per) > 0) {
//                        $sql = <<<EOD
//update no_concepto_periodo tab0 set valor = $valor 
//where tab0.id_concep_nomina = $id_concep
//and tab0.periodo = $id_periodo     
//and tab0.id_tipo_doc = $id_tipo_doc
//and tab0.num_doc = $num_doc 
//EOD;
//                        //Ejecutar SQL
//                        CN_TABLE::executeSQL($sql);
//                    } else {
//                        //insert into no_concepto_periodo (id_concepto_periodo,id_anhos,id_meses,
//                        //periodo,id_tipo_doc,num_doc,id_concep_nomina,fecha_desde,fecha_hasta,
//                        //valor,porcentaje,num_dias) 
//                        //values ('240','2012','11','1','1','1015408219','1',
//                        //to_date('03/12/12','DD/MM/RR'),to_date('31/12/12','DD/MM/RR'),
//                        //'1473178',null,'30');
//                        //Sql
//                        $sql = <<<EOD
//insert into no_concepto_periodo (id_concepto_periodo,id_anhos,id_meses,
//periodo,id_tipo_doc,num_doc,id_concep_nomina,fecha_desde,fecha_hasta,
//valor,porcentaje,num_dias) 
//values (null,$id_anhos,$id_meses,$id_periodo,$id_tipo_doc,'$num_doc',$id_concep,
//to_date('$fecha_ini','yyyy-mm-dd'),to_date('$fecha_fin','yyyy-mm-dd'),
//$valor,null,30)   
//EOD;
//                        //Ejecutar SQL
//                        CN_TABLE::executeSQL($sql);
//                    }
//

                    /*
                     * ANM id->442, 7001 
                     * INCI id->276, 7003 APORTES SALUD OBLIGARTORIO RE - 20130723
                     * Id por campo de la tabla param_concep. Los únicos comprobantes que no se deben inactivar, 
                     * son los que corresponden a SALUD OBLIGATORIA, los cuales se actualizan con el reproceso de cada 6 meses. - 20150420
                     * 
                     */
                    //Sql
                    $sql = <<<EOD
SELECT nvl(ID_CONCEP_APOR_SALOBLI,442) as id_concep FROM NO_PARAM_CONCEP where ID_PARAM_CONCEP = 1 
EOD;
                    //Ejecutar SQL
                    $record_id_concep = CN_TABLE::executeSQL($sql);
                    if (count($record_id_concep) > 0) {
                        $id_concep = $record_id_concep[0]['id_concep'];
                    } else {
                        $id_concep = 442;
                    }
                    $valor = $record['des_salobl'];
                    $dia = $record['diasal_obl'];

                    //El valor debe ser proporcional a los dias - 20130716
                    if ($dia > 30) {
                        $valor = $valor / $dia * 30;
                    }

                    /*
                     * NO_CONCEPTO_FUNC 7001 -> id-442
                     */
                    //Sql
                    $sql = <<<EOD
select tab0.* from no_concepto_func tab0
where tab0.id_concep_nomina = $id_concep
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc   
and tab0.actual = 1 
EOD;
                    //Ejecutar SQL
                    $record_concep_func = CN_TABLE::executeSQL($sql);
                    if (count($record_concep_func) > 0) {

                        //Se cambia, para que inactive ultimo y cree uno nuevo - 20170119
                        $sql = <<<EOD
update no_concepto_func tab0 set estado = 0, actual = 0, fecha_hasta=to_date('$fecha_ini','yyyy-mm-dd')-1
where tab0.id_concep_nomina = $id_concep
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc  
and tab0.actual = 1       
EOD;
                        //Ejecutar SQL
                        CN_TABLE::executeSQL($sql);

                        //Sql
                        $sql = <<<EOD
insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
values (null,$id_tipo_doc,'$num_doc',$id_concep,$valor,null,1,1,
to_date('$fecha_ini','yyyy-mm-dd'),null)  
EOD;
                        //Ejecutar SQL
                        CN_TABLE::executeSQL($sql);
                    } else {
                        //insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
                        //id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
                        //values ('803','1','1015408219','208',null,'1','1','1',
                        //to_date('03/12/12','DD/MM/RR'),null);
                        //Sql
                        $sql = <<<EOD
insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
values (null,$id_tipo_doc,'$num_doc',$id_concep,$valor,null,1,1,
to_date('$fecha_ini','yyyy-mm-dd'),null)  
EOD;
                        //Ejecutar SQL
                        CN_TABLE::executeSQL($sql);
                    }

                    /*
                     * NO_CONCEPTO_PERIODO 7001 -> id-442
                     */
                    //Sql
                    $sql = <<<EOD
select tab0.* from no_concepto_periodo tab0
where tab0.id_concep_nomina = $id_concep
and tab0.periodo = $id_periodo     
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc 
EOD;
                    //Ejecutar SQL
                    $record_concep_per = CN_TABLE::executeSQL($sql);
                    if (count($record_concep_per) > 0) {
                        $sql = <<<EOD
update no_concepto_periodo tab0 set valor = $valor 
where tab0.id_concep_nomina = $id_concep
and tab0.periodo = $id_periodo     
and tab0.id_tipo_doc = $id_tipo_doc
and tab0.num_doc = $num_doc  
EOD;
                        //Ejecutar SQL
                        CN_TABLE::executeSQL($sql);
                    } else {
                        /*
                         * Validar estado del tercero - 20230119::LAVILA
                         */
                        if ($estado != 0) {
                            //insert into no_concepto_periodo (id_concepto_periodo,id_anhos,id_meses,
                            //periodo,id_tipo_doc,num_doc,id_concep_nomina,fecha_desde,fecha_hasta,
                            //valor,porcentaje,num_dias) 
                            //values ('240','2012','11','1','1','1015408219','1',
                            //to_date('03/12/12','DD/MM/RR'),to_date('31/12/12','DD/MM/RR'),
                            //'1473178',null,'30');
                            //Sql
                            $sql = <<<EOD
insert into no_concepto_periodo (id_concepto_periodo,id_anhos,id_meses,
periodo,id_tipo_doc,num_doc,id_concep_nomina,fecha_desde,fecha_hasta,
valor,porcentaje,num_dias) 
values (null,$id_anhos,$id_meses,$id_periodo,$id_tipo_doc,'$num_doc',$id_concep,
to_date('$fecha_ini','yyyy-mm-dd'),to_date('$fecha_fin','yyyy-mm-dd'),
$valor,null,30)   
EOD;
                            //Ejecutar SQL
                            CN_TABLE::executeSQL($sql);
                        }
                    }

//                    
//                    $id_concep = 545;
//                    $valor = $record['des_cerdep'];
//                    /*
//                     * NO_CONCEPTO_FUNC 7004 -> id-545
//                     */
//                    //Sql
//                    $sql = <<<EOD
//select tab0.* from no_concepto_func tab0
//where tab0.id_concep_nomina = $id_concep
//and tab0.id_tipo_doc = $id_tipo_doc
//and tab0.num_doc = $num_doc 
//EOD;
//                    //Ejecutar SQL
//                    $record_concep_func = CN_TABLE::executeSQL($sql);
//                    if (count($record_concep_func) > 0) {
//                        $sql = <<<EOD
//update no_concepto_func tab0 set valor = $valor, fecha_desde=to_date('$fecha_ini','yyyy-mm-dd')
//where tab0.id_concep_nomina = $id_concep
//and tab0.id_tipo_doc = $id_tipo_doc
//and tab0.num_doc = $num_doc 
//EOD;
//                        //Ejecutar SQL
//                        CN_TABLE::executeSQL($sql);
//                    } else {
//                        //insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
//                        //id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
//                        //values ('803','1','1015408219','208',null,'1','1','1',
//                        //to_date('03/12/12','DD/MM/RR'),null);
//                        //Sql
//                        $sql = <<<EOD
//insert into no_concepto_func (id_concep_func,id_tipo_doc,num_doc,
//id_concep_nomina,valor,porcentaje,estado,actual,fecha_desde,fecha_hasta) 
//values (null,$id_tipo_doc,'$num_doc',$id_concep,$valor,null,1,1,
//to_date('$fecha_ini','yyyy-mm-dd'),null)  
//EOD;
//                        //Ejecutar SQL
//                        CN_TABLE::executeSQL($sql);
//                    }
//
//                    /*
//                     * NO_CONCEPTO_PERIODO 7004 -> id-545
//                     */
//                    //Sql
//                    $sql = <<<EOD
//select tab0.* from no_concepto_periodo tab0
//where tab0.id_concep_nomina = $id_concep
//and tab0.periodo = $id_periodo     
//and tab0.id_tipo_doc = $id_tipo_doc
//and tab0.num_doc = $num_doc 
//EOD;
//                    //Ejecutar SQL
//                    $record_concep_per = CN_TABLE::executeSQL($sql);
//                    if (count($record_concep_per) > 0) {
//                        $sql = <<<EOD
//update no_concepto_periodo tab0 set valor = $valor 
//where tab0.id_concep_nomina = $id_concep
//and tab0.periodo = $id_periodo     
//and tab0.id_tipo_doc = $id_tipo_doc
//and tab0.num_doc = $num_doc  
//EOD;
//                        //Ejecutar SQL
//                        CN_TABLE::executeSQL($sql);
//                    } else {
//                        //insert into no_concepto_periodo (id_concepto_periodo,id_anhos,id_meses,
//                        //periodo,id_tipo_doc,num_doc,id_concep_nomina,fecha_desde,fecha_hasta,
//                        //valor,porcentaje,num_dias) 
//                        //values ('240','2012','11','1','1','1015408219','1',
//                        //to_date('03/12/12','DD/MM/RR'),to_date('31/12/12','DD/MM/RR'),
//                        //'1473178',null,'30');
//                        //Sql
//                        $sql = <<<EOD
//insert into no_concepto_periodo (id_concepto_periodo,id_anhos,id_meses,
//periodo,id_tipo_doc,num_doc,id_concep_nomina,fecha_desde,fecha_hasta,
//valor,porcentaje,num_dias) 
//values (null,$id_anhos,$id_meses,$id_periodo,$id_tipo_doc,'$num_doc',$id_concep,
//to_date('$fecha_ini','yyyy-mm-dd'),to_date('$fecha_fin','yyyy-mm-dd'),
//$valor,null,30)   
//EOD;
//                        //Ejecutar SQL
//                        CN_TABLE::executeSQL($sql);
//                    }
                }

                /*
                 * Memcache al 100 porciento
                 */
                MemcacheHandler::getInstance()->set($progress_key, 100);

                /*
                 * COMMIT DE TODAS LAS TRANSACCIONES
                 */
                $this->conn->commit();
                $this->status = 0;
                $this->list_data = array();
                $this->logMessage("[Informe Base Calculo ReteFuente] Actualizar ReteFuente Terminado.");
            } else {

                /*
                 * Memcache al 100 porciento
                 */
                MemcacheHandler::getInstance()->set($progress_key, 100);

                /*
                 * ROLLBACK DE TODAS LAS TRANSACCIONES EN CASO DE QUE OCURRA ALGUN ERROR
                 */
                $this->conn->rollback();

                /*
                 * Mensaje de error
                 */
                $mensajeError = "No hay funcionarios para actualizar ReteFuente.";

                $this->status = 1;
                $this->list_data = array();
                $this->mensajeError = $mensajeError;
                $this->logMessage("[Informe Base Calculo ReteFuente] " . $mensajeError);
            }
        } catch (Exception $e) {
            MemcacheHandler::getInstance()->set($progress_key, 100);

            /**
             * ROLLBACK DE TODAS LAS TRANSACCIONES EN CASO DE QUE OCURRA ALGUN ERROR
             */
            $this->conn->rollback();

            /**
             * Respuesta del servicio
             */
            $this->status = 1;
            $this->mensajeError = "[Informe Base Calculo ReteFuente] Ocurrio un error: " . $e->getMessage();
            $this->list_data = array();
            $this->logMessage("[Informe Base Calculo ReteFuente] ERROR!");
            $this->logMessage($e->getMessage());
        }
    }

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

        /*
         * Variables de calculo
         */
        $dias_calc = 0;
        $dias_ausenc = 0;

        /*
         * Calculo de dias por concepto
         */
        $date1 = new DateTime($fecha_ini);
        $date2 = new DateTime($fecha_ingreso);

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

        /*
         * Calculo de dias de ausencias
         * Se retiran dias habiles segun evaluacion ticket 22446, se toman meses de 30 - 20210701::LAVILA
         * Validacion rango fechas de filtro ini y fin - 20210712::LAVILA
         * Se verifica no_novedad_kardex y se agrega estado = 1 - 20220715::LAVILA
         */
        //Sql
        $sql = <<<EOD
select nvl(sum(dias),0) as dias from(
  select 
  FECHA_RANGO_SIN_TREINTAYUNO(case when novka.fecha_ini < to_date('$fecha_ini','yyyy-mm-dd') then to_date('$fecha_ini','yyyy-mm-dd') else novka.fecha_ini end, 
    case when novka.fecha_fin < to_date('$fecha_fin','yyyy-mm-dd') then novka.fecha_fin else to_date('$fecha_fin','yyyy-mm-dd') end ) as dias,
  dias_habiles_cant( to_char(novka.fecha_ini,'yyyy-mm-dd'), to_char(novka.fecha_fin,'yyyy-mm-dd') ) as dias_habil,
  novka.* ,
  tipnov.afecta_antigu,
  tipnov.afecta_alimen
  from no_novedad_kardex novka
  join no_tip_nov_ka tipnov 
  on novka.id_tip_nov_ka = tipnov.id_tip_nov_ka
  and tipnov.afecta_antigu = 1 
  where
    (
        novka.fecha_ini between to_date('$fecha_ini','yyyy-mm-dd') and to_date('$fecha_fin','yyyy-mm-dd')
        or novka.fecha_fin between to_date('$fecha_ini','yyyy-mm-dd') and to_date('$fecha_fin','yyyy-mm-dd')
    )
    AND novka.num_doc = '$num_doc'
    AND novka.id_tipo_doc = $id_tipo_doc
    and novka.estado = 1
) 
EOD;
        //Ejecutar SQL
        $records = CN_TABLE::executeSQL($sql);

        if (count($records) > 0) {
            $this->logMessage("[Informe Base Calculo ReteFuente] Dias de ausencias: " . $records[0]['dias']);
            $dias_ausenc = $records[0]['dias'];
        }


        $dias = $dias_calc - $dias_ausenc;
        /**
         * Calculo de dias
         */
        $this->logMessage("[Informe Base Calculo ReteFuente] Dias liquidacion: " . $dias);
        return $dias;
    }

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

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

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

        return $formula;
    }

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

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

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

        return $formula;
    }

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

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

            //Sacar caracter y numero(id_concep_nomina) para consulta
            $caracter = substr($key, 0, 1);
            $id_concep_nomina = substr($key, 1);
            $this->logMessage("[Informe Base Calculo ReteFuente] Caracter: " . $caracter . ", numero: " . $id_concep_nomina);

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

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

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

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

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

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

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

            $arrayParametros[$key] = $valor;
        }

        return $arrayParametros;
    }

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

        $vars = array();

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

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

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

        return $arrayParametros;
    }

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

        $agrup = '( ';

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

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

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

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

        $agrup .= ' )';

        return $agrup;
    }

}
