<?php

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

    protected $table_names = array(
        'CA_CREDITO',
        'CA_PUNTO_VENTA',
        'CA_TIPO_CREDITO',
        'CA_CON_CREDITO',
        'TS_BN',
        'TS_CB',
        'TS_TD',
        'USUARIO',
        'INTERCEROS_V'
    ); //tablas para construir el sql, por medio de joins
    protected $table_join_ids = array(
        'CA_PUNTO_VENTA' =>
        array(
            'id_punto_venta' => 'CA_CREDITO'
        ),
        'CA_TIPO_CREDITO' =>
        array(
            'id_tipo_credito' => 'CA_CREDITO'
        ),
        'CA_CON_CREDITO' =>
        array(
            'id_con_credito' => 'CA_CREDITO'
        ),
        'TS_BN,LEFT' =>
        array(
            'id_bn' => 'CA_CREDITO'
        ),
        'TS_CB,LEFT' =>
        array(
            'id_cb' => 'CA_CREDITO'
        ),
        'TS_TD,LEFT' =>
        array(
            'id_ts_td-id' => 'CA_CREDITO'
        ),
        'USUARIO,LEFT' =>
        array(
            'usuariolog-username' => 'CA_CREDITO'
        ),
        'INTERCEROS_V' =>
        array(
            'id_mae_ter' => 'CA_CREDITO'
        )
    ); //si posee tablas para joins, identificar la relacion de los campos con las tablas
    protected $fields = array(
        'CA_CREDITO' =>
        array(
            'id_credito' => 'id_credito',
            'id_anhos' => 'id_anhos',
            'id_punto_venta' => 'id_punto_venta',
            'id_tipo_credito' => 'id_tipo_credito',
            'sec_credito' => 'sec_credito',
            'id_con_credito' => 'id_con_credito',
            'fecha_proceso' => 'fecha_proceso',
            'id_bn' => 'id_bn',
            'id_cb' => 'id_cb',
            'num_doc' => 'num_doc',
            'oficina' => 'oficina',
            'valor' => 'valor',
            'observaciones' => 'observaciones',
            'estado' => 'estado',
            'fecha_anu' => 'fecha_anu',
            'motivo_anu' => 'motivo_anu',
            'fecha' => 'fecha',
            'id_ts_td' => 'id_ts_td',
            'usuariolog' => 'usuariolog',
            'id_mae_ter' => 'id_mae_ter',
            'usuario_anu' => 'usuario_anu'
        ),
        'CA_PUNTO_VENTA' =>
        array(
            'nombre' => 'nombre_pv',
            'descripcion' => 'descripcion_pv'
        ),
        'CA_TIPO_CREDITO' =>
        array(
            'descripcion' => 'descripcion_tc',
            'desc_corta' => 'desc_corta_tc'
        ),
        'CA_CON_CREDITO' =>
        array(
            'descripcion' => 'descripcion_cc',
            'desc_corta' => 'desc_corta_cc'
        ),
        'TS_BN' =>
        array(
            'codigo' => 'codigo_bn',
            'descripcion' => 'descripcion_bn'
        ),
        'TS_CB' =>
        array(
            'numero_cuenta' => 'numero_cuenta'
        ),
        'TS_TD' =>
        array(
            'documento' => 'documento',
            'descripcion' => 'descripcion_td'
        ),
        'USUARIO' =>
        array(
            'num_doc' => 'num_doc_usuario',
            'nombre,||, ,||,apellido' => 'nombre_usuario',
            'num_doc,||, - ,||,nombre,||, ,||,apellido' => 'completo_usuario'
        ),
        'INTERCEROS_V' =>
        array(
            'num_doc' => 'nitocc',
            'razon_soc' => 'razon_soc',
            'num_doc,||, - ,||,razon_soc' => 'tercero'
        )
    ); //por cada tabla especificar los campos del select
    protected $table_field_conditions = array(
        'CA_CREDITO' => array(
//            'id_credito,a' => array('!=' => array(-1)),
            'id_credito' => array('=' => array('id_credito')),
            'id_anhos' => array('=' => array('id_anhos')),
            'id_punto_venta' => array('=' => array('id_punto_venta')),
            'id_tipo_credito' => array('=' => array('id_tipo_credito')),
            'sec_credito' => array('LIKE' => array('sec_credito')),
            'id_con_credito' => array('=' => array('id_con_credito')),
            'fecha_proceso' => array('BETWEENFECHA' => array('fecha_ini', 'fecha_fin')),
            'id_bn' => array('=' => array('id_bn')),
            'id_cb' => array('=' => array('id_cb')),
            'id_ts_td' => array('=' => array('id_ts_td')),
            'estado' => array('=' => array('estado')),
            'valor,a' => array('>=' => array('valor_ini')),
            'valor,b' => array('<=' => array('valor_fin')),
            'valor,c' => array('=' => array('valor_exacto')),
            'id_mae_ter' => array('=' => array('id_mae_ter')),
            'num_doc,a' => array('=' => array('num_doc')),
            'num_doc,b' => array('=' => array('num_doc_nov')),
            '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 $fields_orderBy = array(
        'fecha_proceso', 'sec_credito', 'id_con_credito', 'id_tipo_credito'
    ); //campos para el ordenamiento de la consulta

    /*
     * Variables manejo de log
     */
    //true - consulta de administracion
    protected $is_admin = false;
    //true - la tabla principal de busqueda no es una vista
    protected $is_filtro = true;


    /*
     * ------------VARIABLES PARA SERVICIO DE SUMATORIA - SUM
     *
     */
    protected $summatory_data = array(
        'CA_CREDITO' => array(
            'fields' => array('valor'),
            'labels' => array('id_anhos,Total'),
            'count' => 'sec_credito'
        )
    ); //se especifica por tabla los campos de suma y condiciones de filtro


    /*
     * ------------VARIABLES PARA SERVICIOS CRUD
     */
    protected $id_name = 'id_credito'; //identificador de la tabla
    protected $id_names = array('id_credito'); //llave primaria
    protected $field_names = array('id_anhos', 'id_punto_venta', 'id_tipo_credito', 'sec_credito', 'id_con_credito', 'fecha_proceso',
        'id_bn', 'id_cb', 'num_doc', 'oficina', 'valor', 'observaciones', 'estado', 'fecha_anu', 'motivo_anu', 'fecha', 'id_ts_td',
        'usuariolog', 'id_mae_ter', 'usuario_anu'); //campos de la tabla, sin la llave primaria
    protected $table_name = 'CA_CREDITO'; //tabla en la cual se aplican los cambios
    protected $has_activo = true; //si posee campo en la tabla de nombre activo ---- ESTADO PARA REGALIAS
    protected $has_vigencia = false; //si posee vigencia
    protected $has_cen_op = false; //si posee centro de operacion
    protected $has_id_cia = false; //si posee compañia
    protected $has_secuencia = true; //si posee secuencia la tabla


    /*
     * Manejo de registro log
     */
    protected $id_unico = 'id_credito'; //identificador unico de la tabla

    /**
     * Metodo para add credito
     *
     * @param sfWebRequest $request
     */

    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");


        //sentencia sql
        $sql = <<<EOD
ALTER SESSION SET NLS_DATE_FORMAT = "YYYY-MM-DD"
EOD;
        //ejecuta y obtiene el resultado del sql
        CN_TABLE::executeSQL($sql);

        //manejo de errores
        try {

            //variables obligatorias
            $id_anhos = $request['id_anhos'];
            $id_punto_venta = $request['id_punto_venta'];
            $id_tipo_credito = $request['id_tipo_credito'];
            $id_con_credito = $request['id_con_credito'];
            $fecha_proceso = $request['fecha_proceso'];
//            $fecha_proceso = CN_TABLE::fechaSistema();
            $num_doc = $request['num_doc'];
            $valor = $request['valor'];
            $fecha = $request['fecha'];
            $id_ts_td = $request['id_ts_td'];
            $username = $request['username'];
            $id_mae_ter = $request['id_mae_ter'];

            //variables NO obligatorias
            $oficina = 'null';
            if (isset($request['oficina'])) {
                $oficina = "'" . $request['oficina'] . "'";
            }
            $observaciones = 'null';
            if (isset($request['observaciones'])) {
                $observaciones = "'" . $request['observaciones'] . "'";
            }
            $id_bn = 'null';
            if (isset($request['id_bn'])) {
                $id_bn = $request['id_bn'];
            }
            $id_cb = 'null';
            if (isset($request['id_cb'])) {
                $id_cb = $request['id_cb'];
            }

            /*
             * OBTENER SECUENCIA PARA EL CRÉDITO
             * si no esta creada crearla
             */
            //sentencia sql
            $sql = <<<EOD
SELECT * FROM ca_consecutivo_cre
WHERE id_anhos = $id_anhos
AND id_punto_venta = $id_punto_venta
AND id_tipo_credito = $id_tipo_credito
EOD;

            //ejecuta el sql
            $result = CN_TABLE::executeSQL($sql);

            //validar si hay registro de secuencia credito
            if (count($result) == 1) {

                //valores de la secuencia credito
                $sec_credito = $result[0]['consecutivo'] + 1;
                $this->logMessage("[CREDITO] La secuencia = " . $sec_credito);
            } else {
                $sec_credito = 1;
                $this->logMessage("[CREDITO] La secuencia = " . $sec_credito);
            }



            //sentencia sql ingresar CA_CREDITO
            $sql = <<<EOD
Insert into CA_CREDITO 
    (ID_CREDITO,ID_ANHOS,ID_PUNTO_VENTA,ID_TIPO_CREDITO,SEC_CREDITO,ID_CON_CREDITO,FECHA_PROCESO,ID_BN,ID_CB,NUM_DOC,OFICINA,VALOR,OBSERVACIONES,ESTADO,FECHA_ANU,MOTIVO_ANU,FECHA,ID_TS_TD,USUARIOLOG,ID_MAE_TER)
    values (null,$id_anhos,$id_punto_venta,$id_tipo_credito,$sec_credito,$id_con_credito,to_date('$fecha_proceso','yyyy-mm-dd'),$id_bn,$id_cb,$num_doc,$oficina,$valor,$observaciones,1,null,null,to_date('$fecha','yyyy-mm-dd'),$id_ts_td,'$username',$id_mae_ter)
EOD;

            //ejecuta el sql
            CN_TABLE::executeSQL($sql);

            /*
             * INICIO ACTUALIZAR SECUENCIA DEBITO
             */

            if (count($result) == 1) {
                $this->logMessage("[CREDITO] La secuencia existe.");

                //valores de la secuencia credito
                $sec_credito = $result[0]['consecutivo'] + 1;
                $id_consecutivo_cred = $result[0]['id_consecutivo_cred'];

                //sentencia sql actualizar valores  de secuencia credito
                $sql = <<<EOD
UPDATE CA_CONSECUTIVO_CRE SET consecutivo = $sec_credito  WHERE id_consecutivo_cred = $id_consecutivo_cred
EOD;

                //ejecuta el sql
                CN_TABLE::executeSQL($sql);
                $this->logMessage("[CREDITO] SQL de actualizacion secuencia credito: " . $sql);
            } else {
                $this->logMessage("[CREDITO] La secuencia NO existe.");

                $sec_credito = 1;

                //sentencia sql
                $sql = <<<EOD
Insert into CA_CONSECUTIVO_CRE (ID_CONSECUTIVO_CRED,ID_TIPO_CREDITO,ID_ANHOS,ID_PUNTO_VENTA,CONSECUTIVO) values ( null, $id_tipo_credito, $id_anhos, $id_punto_venta, $sec_credito)
EOD;
                //ejecuta el sql
                CN_TABLE::executeSQL($sql);
                $this->logMessage("[CREDITO] SQL de creacion secuencia credito: " . $sql);
            }
            /*
             * FIN ACTUALIZAR SECUENCIA DEBITO
             */



            // ultimo registro insertado CA_CREDITO
            $sql = <<<EOD
select * from CA_CREDITO
where id_credito = (
      select
      --max (id_credito)
      id_credito
      from CA_CREDITO
      where
      id_anhos = $id_anhos
      AND id_punto_venta = $id_punto_venta
      AND id_tipo_credito = $id_tipo_credito
      AND sec_credito = (
              SELECT CONSECUTIVO
              FROM ca_consecutivo_cre
              WHERE id_anhos = $id_anhos
              AND id_punto_venta = $id_punto_venta
              AND id_tipo_credito = $id_tipo_credito
      )
)
and id_anhos = $id_anhos
AND id_punto_venta = $id_punto_venta
AND id_tipo_credito = $id_tipo_credito
EOD;
            //ejecuta y obtiene el resultado del sql
            $resultado = CN_TABLE::executeSQL($sql);
//            $this->logMessage("SQL CREDITO nueva. " . $sql);

            /*
             * Verifica que sea un registro para insertar las referencias del debito
             * y vienen registros para las referenciass
             */
            if (count($resultado) == 1) {

                $id_credito = $resultado[0]['id_credito'];

                /*
                 * INICIO variables por defecto para el registro de log
                 */ {
                    //obtiene el valor para su identificador unico
                    $id_tabla = $id_credito;

                    //validar vigencia
                    $id_vigencia = 'null';
                    if ($this->has_vigencia) {
                        if (isset($request['id_anhos'])) {
                            $id_vigencia = $request['id_anhos'];
                        }
                    }

                    //validar centro de operacion
                    $id_cen_op = 'null';
                    if ($this->has_cen_op) {
                        if (isset($request['id_cen_op'])) {
                            $id_cen_op = $request['id_cen_op'];
                        }
                    }

                    $id_cia = 'null';
                    if ($this->has_id_cia) {
                        if (isset($request['id_cia'])) {
                            $id_cia = $request['id_cia'];
                        }
                    }

                    //obtener id maestro tabla
                    $id_mae_bd = CN_TABLE::consultarIdTablaBD('CA_CREDITO');

                    //3 - indica operacion de adicionar de registro
                    $id_ope_bd = 3;

                    //id del maestro tercero
                    $id_mae_ter = 1;
                    if (isset($request['id_username'])) {
                        $id_mae_ter = $request['id_username'];
                    }
                    //el username desde qebsafiERP
                    $usuario = 'admin';
                    if (isset($request['username']) && $request['username'] != '') {
                        $usuario = $request['username'];
                    }
                    //comando que identifica la funcionalidad
                    $comando = 'sin comando';
                    if (isset($request['comando'])) {
                        $comando = $request['comando'];
                    }

                    /*
                     * Construir observacion
                     */
                    $observacion = "'Se adiciono id_credito : " . $id_tabla . " desde la funcionalidad: " . $comando . "'";


                    $id_punto_venta_log = 'null';
                    if (isset($request['punto_venta_log'])) {
                        $id_punto_venta_log = $request['punto_venta_log'];
                    }
                }
                /*
                 * FNI variables por defecto para el registro de log
                 */

                /*
                 * registro de consulta en tabla de log
                 */
                $sql = CN_TABLE::registroTableLog($id_tabla, $id_vigencia, $id_cen_op, $id_cia, $id_mae_bd, $id_ope_bd, $id_mae_ter, $usuario, $comando, $observacion, $id_punto_venta_log);
            }

            $this->list_data = $resultado;
            $this->logMessage("Total filas: " . count($resultado));
        } catch (Exception $e) {

            $this->status = 1;
            $this->mensajeError = "ERROR!!!";
            $this->list_data = array();
            $this->logMessage("ERROR!!!");
            $this->logMessage($e->getMessage());
        }
    }

    /**
     * Metodo para anular el credito
     *
     * @param sfWebRequest $request
     */
    public function executeRemove(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");

        //manejo de errores
        try {
            //variables obligatorias
            $id_credito = $request['id_credito'];
            $fecha_sistema = $request['fecha_proceso'];
//            $fecha_sistema = CN_TABLE::fechaSistema();
            $motivo_anu = 'null';
            if (isset($request['motivo_anu'])) {
                if ($request['motivo_anu'] != 'null') {
                    $motivo_anu = "'" . $request['motivo_anu'] . "'";
                } else {
                    $motivo_anu = 'null';
                }
            }

            /*
             * INICIO variables por defecto para el registro de log
             */ {
                //obtiene el valor para su identificador unico
                $id_tabla = $id_credito;

                //validar vigencia
                $id_vigencia = 'null';
                if ($this->has_vigencia) {
                    if (isset($request['id_anhos'])) {
                        $id_vigencia = $request['id_anhos'];
                    }
                }

                //validar centro de operacion
                $id_cen_op = 'null';
                if ($this->has_cen_op) {
                    if (isset($request['id_cen_op'])) {
                        $id_cen_op = $request['id_cen_op'];
                    }
                }

                $id_cia = 'null';
                if ($this->has_id_cia) {
                    if (isset($request['id_cia'])) {
                        $id_cia = $request['id_cia'];
                    }
                }

                //obtener id maestro tabla
                $id_mae_bd = CN_TABLE::consultarIdTablaBD('CA_CREDITO');

                //5 - indica operacion de anulacion de registro
                $id_ope_bd = 5;

                //id del maestro tercero
                $id_mae_ter = 1;
                if (isset($request['id_username'])) {
                    $id_mae_ter = $request['id_username'];
                }
                //el username desde qebsafiERP
                $usuario = 'admin';
                if (isset($request['username']) && $request['username'] != '') {
                    $usuario = $request['username'];
                }
                $usuario_anu = $usuario;
                //comando que identifica la funcionalidad
                $comando = 'sin comando';
                if (isset($request['comando'])) {
                    $comando = $request['comando'];
                }

                /*
                 * Construir observacion
                 */
                $observacion = "'Se anulo id_credito : " . $id_tabla . " desde la funcionalidad: " . $comando . "'";


                $id_punto_venta_log = 'null';
                if (isset($request['punto_venta_log'])) {
                    $id_punto_venta_log = $request['punto_venta_log'];
                }
            }
            /*
             * FIN variables por defecto para el registro de log
             */


            $resultado = array();


            //sentencia sql
            $sql = <<<EOD
Select
Cre.*,
Exc.Id_Credito as id_credito_exc,
Exc.Id_Excedente,
Exc.Valor As Valor_Exc,
nvl(Exc.En_Uso,-1) as en_uso,
Exc.Id_Credito_Aplicado
From Ca_Credito Cre

left Join Ca_Excedentes Exc
On Exc.Id_Credito = Cre.Id_Credito

Where Cre.Id_Credito = $id_credito
EOD;
            //ejecuta el sql
            $result_cre = CN_TABLE::executeSQL($sql);

            /*
             * Validar estado activo credito
             */
            if ($result_cre[0]['estado'] == 1) {
                $this->logMessage("[CREDITO] El estado del credito es activo.");

                /*
                 * 1 - En uso
                 * 0 - No esta en uso
                 * (-1) - No posee excedente
                 */
                $estado = $result_cre[0]['en_uso'];
                $sec_credito = $result_cre[0]['sec_credito'];

                //No posee excedentes en uso
                if ($estado <= 0) {
                    $this->logMessage("[CREDITO] No posee excedentes en uso.");

                    /*
                     * anular credito
                     * Incidente #6671 - 20170712
                     */
                    //sentencia sql
                    $sql = <<<EOD
UPDATE CA_CREDITO SET estado = 0, fecha_anu = '$fecha_sistema', motivo_anu = $motivo_anu, usuario_anu = '$usuario_anu'
            WHERE id_credito = $id_credito
EOD;
//                $this->logMessage("---" . $sql);
                    //ejecuta el sql
                    CN_TABLE::executeSQL($sql);

                    /*
                     * registro de consulta en tabla de log
                     */
                    $sql = CN_TABLE::registroTableLog($id_tabla, $id_vigencia, $id_cen_op, $id_cia, $id_mae_bd, $id_ope_bd, $id_mae_ter, $usuario, $comando, $observacion, $id_punto_venta_log);


                    /*
                     * INICIO Actualizar excedente si el credito es de un excedente
                     */

                    $sql = <<<EOD
Select
Cre.*,
Exc.Id_Credito as id_credito_exc,
Exc.Id_Excedente,
Exc.Valor As Valor_Exc,
nvl(Exc.En_Uso,-1) as en_uso,
Exc.Id_Credito_Aplicado
From Ca_Credito Cre

Join Ca_Excedentes Exc
On Exc.Id_Credito_Aplicado = Cre.Id_Credito

Where Cre.Id_Credito = $id_credito
EOD;
                    //ejecuta el sql
                    $result = CN_TABLE::executeSQL($sql);

                    if (count($result) > 0) {
                        $this->logMessage("[CREDITO] Entro en actualizar excedente.");


                        $id_excedente = $result[0]['id_excedente'];

                        //sentencia sql
                        $sql = <<<EOD
UPDATE CA_EXCEDENTES SET EN_USO = 0 , ID_CREDITO_APLICADO = null
            WHERE id_excedente = $id_excedente AND id_credito_aplicado = $id_credito
EOD;
//            $this->logMessage("---" . $sql);
                        //ejecuta el sql
                        CN_TABLE::executeSQL($sql);
                    }
                    /*
                     * FIN Actualizar excedente si el credito es de un excedente
                     */




                    /*
                     * INICIO Actualizar tabla CA_SALDO
                     */
                    //obtener id_debitos para el credito detalle del credito anulado
                    //sentencia sql
                    $sql = <<<EOD
SELECT * FROM CA_CREDITO_VENCIMIENTOS
where id_credito = $id_credito
EOD;
                    //ejecuta el sql
                    $result = CN_TABLE::executeSQL($sql);

                    if (count($result) > 0) {



                        //eliminar registros de la tabla CA_SALDO para cada debito en el periodo y fecha de anulacion y posteriores
                        foreach ($result as $result_fila) {

                            $id_debito = $result_fila['id_debito'];
                            $id_vencimiento = $result_fila['id_vencimiento'];

                            /*
                             * cancelado vencimiento
                             */
                            //sentencia sql
                            $sql = <<<EOD
UPDATE CA_VENCIMIENTOS SET cancelado = 0
            WHERE id_debito = $id_debito AND id_vencimiento = $id_vencimiento AND estado = 1
EOD;
//            $this->logMessage("---" . $sql);
                            //ejecuta el sql
                            CN_TABLE::executeSQL($sql);


                            /**
                             * Anula los debitos automaticos que se relacionan con el debito cancelado - 20180206
                             */
                            //sentencia sql
                            $sql = <<<EOD
select
to_char((select max(cre.fecha_proceso) from ca_credito cre where cre.id_credito = $id_credito), 'yyyy-mm-dd') as text_date,                                         
(select max(cre.sec_credito) from ca_credito cre where cre.id_credito = $id_credito) as sec_credito,
(select max(cre.id_anhos) from ca_credito cre where cre.id_credito = $id_credito) as id_anhos_credito,                                        
debbase.sec_debito,
debbase.id_anhos as id_anhos_aut,
debaut.*
from ca_debito_automatico debaut

join ca_debito_vencimientos deb 
on deb.id_debito = debaut.id_debito

join ca_debito debbase
on debbase.id_debito = debaut.id_debito_base

where
debaut.id_debito_base in (
    select 
    deb.id_debito 
    from ca_debito_vencimientos deb
    
    where
    deb.id_debito in (select ca_debito_automatico.id_debito_base from ca_debito_automatico)
    and deb.cancelado = 0
    and deb.estado = 1
)
and deb.estado = 0
and deb.cancelado = 0
and debaut.estado = 1
and debaut.id_debito_base in ( select id_debito from ca_debito_vencimientos where ca_debito_vencimientos.id_vencimiento = $id_vencimiento )
and deb.motivo_anu_ven like '%NC.$sec_credito%'                                    
EOD;
                            //ejecuta el sql
                            $result_automatico = CN_TABLE::executeSQL($sql);

                            foreach ($result_automatico as $value_automatico) {

                                $id_debito_aut = $value_automatico['id_debito'];

                                /*
                                 * Actualiza vencimiento
                                 */
                                //sentencia sql
                                $sql = <<<EOD
UPDATE CA_VENCIMIENTOS SET estado = 1, fecha_anu = '', motivo_anu = ''
        where id_debito = $id_debito_aut
EOD;
                                //ejecuta el sql
                                CN_TABLE::executeSQL($sql);

                                /**
                                 * Actualiza debito
                                 */
                                //sentencia sql
                                $sql = <<<EOD
UPDATE ca_debito set usuario_anu = '', estado = 1, fecha_anu = '', motivo_anu = ''
        where id_debito = $id_debito_aut
EOD;
                                //ejecuta el sql
                                CN_TABLE::executeSQL($sql);
                            }


                            /*
                             * Obtiene las vigencias y periodos que se encuentran en los saldos
                             */
                            $sql = <<<EOD
select distinct
       sal.id_anhos, sal.id_meses , mes.descripcion
       from CA_SALDOS sal
join meses mes on
       sal.id_meses = mes.id_meses
order by
       sal.id_anhos desc,
       sal.id_meses desc
EOD;

                            //Ejecuta sql
                            $saldos_rec = CN_TABLE::executeSQL($sql);

                            //Valida si estan vacio los saldos
                            if (!empty($saldos_rec)) {


                                //Obtiene valores de la ultima fila
                                $anho = $saldos_rec[0]['id_anhos'];
                                $mes = $saldos_rec[0]['id_meses'];

                                //fecha del sistema
                                $anho_req = date('Y'); //anho completo cuatro digitos
                                $mes_req = date('n'); //mes con dos digitos

                                do {

                                    $saldosAnt = CN_TABLE::fechaAnterior($anho_req, $mes_req); //obtener anho-mes anterior

                                    $saldos = array(
                                        'id_anhos' => $anho_req,
                                        'id_meses' => $mes_req
                                    );

                                    $this->logMessage(" [Update]  Remover y generar saldo.");
                                    $this->removeSaldo($saldos, $saldosAnt, $id_debito); //borra y genera nuevos saldos - por recaudo

                                    $saldos = CN_TABLE::fechaSiguiente($anho_req, $mes_req); //obtener anho-mes siguiente
                                    //variables del request - actualiza por siguientes
                                    $anho_req = $saldos['id_anhos'];
                                    $mes_req = $saldos['id_meses'];

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

                                    $this->logMessage(" [Update]  Anho - Mes for." . $anho_req . " - " . $mes_req);
                                    $this->logMessage(" [Update]  Anho - Mes ultimo." . $anho . " - " . $mes);
                                } while ($anho_req <= $anho && $mes_req <= $mes);



                                $this->status = 0;
                                $this->list_data = array();
                            } else {

//                            $this->status = 1;
                                $this->list_data = array();
                                $this->logMessage("No hay saldos de los debitos.");
                            }
                        }
                    } else {

//                    $this->status = 1;
                        $this->mensajeError = "No hay debito para el ...";
                        $this->logMessage("No hay debito para el ...");
                    }

                    /*
                     * FIN Actualizar tabla RE_SALDO
                     */


                    //resultado del debito anulado
                    $resultado[] = array(
                        'id_credito' => $id_credito,
                        'estado' => false,
                        'fecha_anu' => $fecha_sistema,
                        'motivo_anu' => $motivo_anu/* ,
                              'valor_bruto' => 0,
                              'valor_total' => 0 */
                    );

                    /*
                     * Anula movimiento banco
                     * Se actualiza validacion si no hay mov banco, id_mov_banc != 0 - 20221205::LAVILA
                     */
                    //sentencia sql
                    $sql = <<<EOD
declare

  credito number := $id_credito;
  id_mov_banc number := 0;
  l_query  VARCHAR2(1000) ;

begin

  -- Obtener ca_credito por id_credito  
  
  -- Recorer ca_credito que poseean fconcepto credito que aplica banco
  -- Factura pago Anulada estado en 0
  for recordindex in (    
    select 
    cre.*
    from ca_credito cre
    join ca_con_credito concre on concre.id_con_credito = cre.id_con_credito and concre.aplica_bn = 1
    where cre.id_credito = credito  
  )
  loop
  
  -- Obtener por cada una el id del movimiento de banco        
      l_query := q'[SELECT nvl(max(mb.id),0) as id FROM ts_mov_banc mb WHERE mb.numero_doc = ']' ||  recordindex.num_doc || q'[']' ||
                  ' and mb.id_mae_ter = ' || recordindex.id_mae_ter || 
                  ' and mb.id_ts_bn = ' || recordindex.id_bn || ' and mb.id_ts_cb = ' || recordindex.id_cb || 
                  ' and mb.id_ts_td = ' || recordindex.id_ts_td || 
                  ' and mb.valor = '  || recordindex.valor || ' ' ||
                  q'[and mb.observaciones like '%]' || RecordIndex.sec_credito || q'[%']' || ' '  ;
      
      --dbms_output.put_line(l_query) ;
      execute immediate l_query into id_mov_banc ;
      --DBMS_OUTPUT.PUT_LINE(id_mov_banc) ;

    if id_mov_banc != 0     
     then
        -- Por cada una anular movimiento banco
        update  ts_mov_banc set estado = 1 where id = id_mov_banc;

        -- Por cada una crear movimiento banco anulado
        insert into ts_anu_mov_banc ( id_anu_mov_banc, id_mov_banc, fecha_anul, concepto, observaciones, usuario, fecha_log ) 
        values ( null, id_mov_banc, trunc(recordindex.fecha_anu), 'ANULACIÓN CRÉDITO ',
        'ANULACIÓN CRÉDITO No. ' || RecordIndex.sec_credito , '$usuario', trunc(sysdate) );
    END IF; 
  

  END LOOP;

end ;

EOD;
                    //ejecuta el sql
                    CN_TABLE::executeSQL($sql);


                    $this->list_data = $resultado;
                    $this->logMessage("Se anulo el CREDITO.");
                } else {

                    $mensaje = "[CREDITO] Posee excedente en uso.";
                    $this->status = 1;
                    $this->mensajeError = $mensaje;
                    $this->list_data = array();
                    $this->logMessage($mensaje);
                }
            } else {

                $mensaje = "[CREDITO] No se puede anular el credito, esta anulado.";
                $this->status = 1;
                $this->mensajeError = $mensaje;
                $this->list_data = array();
                $this->logMessage($mensaje);
            }
        } catch (Exception $e) {

            $this->status = 1;
            $this->mensajeError = "ERROR!!!";
            $this->list_data = array();
            $this->logMessage("ERROR!!!");
            $this->logMessage($e->getMessage());
        }
    }

    /**
     * Remueve los saldo e inserta los nuevos calulos
     *
     * @param sfWebRequest $request
     */
    public static function removeSaldo($saldos, $saldosAnt, $id_debito) {

        //manejo de errores
        try {

            //Obtener valores
            $anho = $saldos['id_anhos'];
            $mes = $saldos['id_meses'];

            $anho_ant = $saldosAnt['id_anhos'];
            $mes_ant = $saldosAnt['id_meses'];

            /*
             * Elimina saldos por vigencia/periodo
             */
            $sql = <<<EOD
DELETE FROM CA_SALDOS

WHERE  ID_DEBITO = $id_debito
       AND ID_ANHOS =   $anho
       AND ID_MESES =  $mes
EOD;

            //Ejecuta sql
            CN_TABLE::executeSQL($sql);

            $sql = <<<EOD
INSERT INTO CA_SALDOS

SELECT * FROM
(

    select

    tab1.id_debito,
    tab1.id_vencimiento,
    tab1.anho,
    tab1.mes,
    NVL( sal.saldo_actual , 0 ) as saldo_anterior,
    --tab1.recaudado_distri as recaudado,
    CASE
         WHEN sal.debitos_mes < 0
              THEN 0
         ELSE tab1.debitos_mes
    END as debitos_mes,

    tab1.creditos_mes as creditos_mes,

    (NVL( sal.saldo_actual , 0 )) +
    (CASE
         WHEN sal.debitos_mes < 0
              THEN 0
         ELSE tab1.debitos_mes
    END )- tab1.creditos_mes as saldo_actual

    from (

        select


        tab0.id_debito,
        tab0.id_vencimiento,
        --to_char(tab0.fecha_proc,'yyyy') as anho,
        '$anho' as anho,
        --to_char(tab0.fecha_proc,'mm') as mes,
        '$mes' as mes,
        tab0.debitos_mes,
        SUM(tab0.creditos_mes) as creditos_mes

        from (

                  SELECT

                  debcre.id_debito,
                  debcre.fecha_proceso,
                  debcre.valor_total,
                  debcre.estado,
                  debcre.fecha_anu,
                  debcre.id_vencimiento,
                  debcre.fecha_vence,
                  debcre.estado_ven,
                  debcre.fecha_anu_ven,
                  debcre.cancelado,
                  debcre.id_credito_detalle,
                  debcre.valor_abono,
                  debcre.id_credito,
                  debcre.fecha_proceso_cre,
                  debcre.valor_cre,
                  debcre.estado_cre,
                  debcre.fecha_anu_cre,

                   /*colocar el respectivo valor debito segun el registro*/

                  CASE
                     -- segun el estado del vencimiento
                     WHEN debcre.estado_ven = 0
                          THEN
                                -- segun fecha de anulacion vencimiento
                                CASE
                                   WHEN To_Char(Debcre.Fecha_Proceso,'yyyy') = To_Char(Debcre.fecha_anu_ven,'yyyy') And To_Char(Extract(Month From Debcre.Fecha_Proceso)) = To_Char(Extract(Month From debcre.fecha_anu_ven))
                                        THEN 0
                                   WHEN To_Char(Debcre.fecha_anu_ven,'yyyy') = '$anho' And To_Char(Extract(Month From Debcre.fecha_anu_ven)) = '$mes'
                                        THEN -debcre.valor
                                   When To_Char(Debcre.Fecha_Proceso,'yyyy') >= '$anho' And To_Char(Extract(Month From Debcre.Fecha_Proceso)) >= '$mes'
                                        And To_Char(Debcre.fecha_anu_ven,'yyyy') <= '$anho' And To_Char(Extract(Month From Debcre.fecha_anu_ven)) > '$mes'
                                        THEN debcre.valor
                                   Else 0
                                /*
                                   WHEN to_char(debcre.fecha_proceso,'yyyy')  = to_char(debcre.fecha_anu,'yyyy') and to_char(debcre.fecha_proceso,'mm') = to_char(debcre.fecha_anu,'mm')
                                        THEN 0
                                   WHEN to_char(debcre.fecha_anu,'yyyy') = '$anho' and to_char(Extract(Month From Debcre.fecha_anu)) = '$mes'
                                        Then -Debcre.Valor_Total
                                   When To_Char(Debcre.Fecha_Anu,'yyyy') >= '$anho' And To_Char(Debcre.Fecha_Anu,'mm') > '$mes'
                                        and to_char(debcre.fecha_proceso,'yyyy') <= '$anho' and to_char(Extract(Month From Debcre.Fecha_Proceso)) != '$mes'
                                        THEN 0
                                   WHEN ( to_char(debcre.fecha_anu,'yyyy') = '$anho' and to_char(debcre.fecha_anu,'mm') < '$mes' )
                                        or
                                        ( to_char(debcre.fecha_anu,'yyyy') < '$anho')
                                        THEN 0
                                   ELSE debcre.valor_total
                                   */
                                END

                    WHEN debcre.estado_ven = 1
                          Then
                              --segun fecha de proceso de debito
                              Case
                                   WHEN to_char(debcre.fecha_proceso,'yyyy') = '$anho' and to_char(Extract(Month From Debcre.Fecha_Proceso)) = '$mes'
                                        THEN debcre.valor
                                   ELSE 0
                              END

                     ELSE 0
                  END AS debitos_mes,

                 /*colocar el respectivo valor credito segun el registro*/

                  Case
                     -- segun el estado del credito
                     WHEN debcre.estado_cre = 0
                          Then
                                -- segun fecha anulacion credito
                                Case
                                   When To_Char(Debcre.Fecha_Proceso_Cre,'yyyy') = To_Char(Debcre.Fecha_Anu_Cre,'yyyy') And To_Char(Extract(Month From Debcre.Fecha_Proceso_Cre)) = To_Char(Extract(Month From Debcre.Fecha_Anu_Cre))
                                        Then 0
                                   When To_Char(Debcre.Fecha_Anu_Cre,'yyyy') = '$anho' And To_Char(Extract(Month From Debcre.Fecha_Anu_Cre)) = '$mes'
                                        Then -Debcre.Valor_Abono
                                   When To_Char(Debcre.Fecha_Proceso_Cre,'yyyy') >= '$anho' And To_Char(Extract(Month From Debcre.Fecha_Proceso_Cre)) >= '$mes'
                                        And To_Char(Debcre.fecha_anu_cre,'yyyy') <= '$anho' And To_Char(Extract(Month From Debcre.fecha_anu_cre)) > '$mes'
                                        Then debcre.valor_abono
                                   Else 0
                                   /*
                                   WHEN to_char(debcre.fecha_anu_cre,'yyyy') = '$anho' and to_char(Extract(Month From Debcre.fecha_anu_cre)) = '$mes'
                                        THEN 0
                                   WHEN to_char(debcre.fecha_proceso_cre,'yyyy') = to_char(debcre.fecha_anu_cre,'yyyy') and to_char(debcre.fecha_proceso_cre,'mm') = to_char(debcre.fecha_anu_cre,'mm')
                                        THEN 0
                                   ELSE -debcre.valor_abono
                                   */
                                END

                    WHEN Debcre.Estado_Cre = 1
                          Then
                              --segun fecha de proceso de credito
                              Case
                                   WHEN To_Char(Debcre.Fecha_Proceso_Cre,'yyyy') = '$anho' And To_Char(Extract(Month From Debcre.Fecha_Proceso_Cre)) = '$mes'
                                        THEN Debcre.Valor_Abono
                                   ELSE 0
                              END

                     ELSE 0
                  END AS  creditos_mes

                  FROM CA_DEBITO_CREDITO debcre

                where
                debcre.id_debito = $id_debito
                /*to_char(debcre.fecha_proceso,'mm') = '11' */


          )tab0
          group by
          tab0.id_debito,
          tab0.id_vencimiento,
          to_char(tab0.fecha_proceso,'yyyy'),
          to_char(tab0.fecha_proceso,'mm'),
          tab0.debitos_mes

          order by
          tab0.id_debito

    )tab1

    left join CA_SALDOS sal
    on sal.id_debito = tab1.id_debito
    and sal.id_anhos = $anho_ant
    and sal.id_meses = $mes_ant
    --and sal.saldo_actual <> 0

    order by
    tab1.id_debito

)
where
saldo_anterior !=0
or debitos_mes !=0
or creditos_mes !=0
or saldo_actual !=0

EOD;

            //Ejecuta sql
            CN_TABLE::executeSQL($sql);

//            $this->list_data = array();
//            $this->logMessage("Se ingreso saldos");
        } catch (Exception $e) {

//            $this->status = 1;
//            $this->totalRows = 0;
//            $this->startRow = 0;
//            $this->endRow = 0;
//            $this->list_data = array();
//            $this->logMessage("ERROR!!!");
//            $this->logMessage($e->getMessage());
        }
    }

    // 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;

        /*
         *  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;

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

}
