<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Manejador de consultas sql
 *
 * @author narange
 */
abstract class sfQuery extends sfAPIActions {
    /*
     * Valores por defecto
     */

    protected $id_name = null; //llave unica - solo un valor
    protected $id_names = null; // llave primaria
    protected $field_names = null; // campos de las tablas - sin llave primaria
    protected $table_name = null; // nombre de la tablas
    protected $has_id_cia = false; //si posee campo de cia en la tabla
    protected $has_activo = false; //si posee campos booleanos
    protected $is_admin = false; // si pertenece al menu de admin - param
    protected $log_list = false; //false - Registrar log para listar - consultar
    protected $log_crud = false; //false - Registrar log para add - update - remove

    /*
     * Observacion perzonalizada
     */
    protected $observacion_list = false;
    protected $observacion_add = false;
    protected $observacion_update = false;
    protected $observacion_remove = false;

    /*
     * Errors GWT
     */
    protected $STATUS_FAILURE = 3; //-1
    protected $STATUS_LOGIN_INCORRECT = -5;
    protected $STATUS_LOGIN_REQUIRED = -7;
    protected $STATUS_LOGIN_SUCCESS = -8;
    protected $STATUS_MAX_LOGIN_ATTEMPTS_EXCEEDED = -6;
    protected $STATUS_SERVER_TIMEOUT = -100;
    protected $STATUS_SUCCESS = 0;
    protected $STATUS_TRANSPORT_ERROR = -90;
    protected $STATUS_VALIDATION_ERROR = -4;

    /**
     * Obtener records de la base de datos
     * segun parametros de cada servicio
     * 
     * @param sfWebRequest $request
     */
    public function executeList(sfWebRequest $request) {

        $cond_container = null;
        $cond_or_container = null;
        $sortBy = null;

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


        /*
         * Variables globales del proyecto
         */
        $modulo = sfConfig::get('app_modulo');
        $usuarioERP = sfConfig::get('app_usuarioERP');
        $claveERP = sfConfig::get('app_claveERP');
        $tablaComandos = sfConfig::get('app_tablaComandos');


        //recorrer array de variables obligatorios en el request
        $validar_field_obl = false;
        if (isset($this->table_field_obligatory)) {

            $this->logMessage("[sfQuery] Entra validación campos obligatorios.");

            foreach ($this->table_field_obligatory as $value) {

                //log del valor del array
                $this->logMessage("[sfQuery] Valor: " . $value);

                //validar que en el request esta la variable
                if (isset($request[$value])) {

//                    $this->logMessage("//////////////////" . $request[$value]);

                    $validar_field_obl = false;
                } else {

//                    $this->logMessage("+++++++++++++++++++++");

                    $validar_field_obl = true;
                    break;
                }
            }
        }

        //validacion de subcuentas por digitos - arreglar para todos los casos
        if (isset($request['subc_ini']) || isset($request['subc_fin'])) {
            $validar_field_obl = false;
        }



        //validar errores de procedimiento
        try {


            /*
             * validar valores obligatorios
             * campos obligatorios de filtro - estan en el request
             */
            if ($validar_field_obl) {

                //mensaje de log
                $mensaje = "[LIST sfQuery] No estan las variables obligatorias.";

                //variable de json
                $this->list_errors = array(
                    'operacion' => "LIST"
                );

                $this->logMessage($mensaje);
                $this->logMessage("status -1");

                $this->status = $this->STATUS_FAILURE;
                $this->mensajeError = $mensaje;
                $this->list_data = array();
            } else {


                /*
                 * variables por defecto para el registro de log
                 */
                $id_tabla = 'null';

                //1 - indica operacion de consultar
                //2 - indica operacion de actualizar
                //3 - indica operacion de adicionar
                //4 - indica operacion de eliminar
                //5 - indica operacion de anular
                $id_mae_bd = 'null';
                /*
                 * valida si posee solo una tabla para en los $table_names y es servicio de filtro
                 * para buscar el id de la tabla
                 */
                if (count($this->table_names) > 0 && $this->is_filtro) {

                    $this->logMessage("[sfQuery] Tabla principal de consulta para el filtro: " . $this->table_names[0]);
                    $id_mae_bd = CN_TABLE::consultarIdTablaBD($this->table_names[0]);
                }


                //1 - indica operacion de consultar
                //2 - indica operacion de actualizar
                //3 - indica operacion de adicionar
                //4 - indica operacion de eliminar
                //5 - indica operacion de anular
                $id_ope_bd = 1;

                //id del usuario
                $usuario = 1;
                if (isset($request['id_username'])) {
                    $usuario = $request['id_username'];
                }

                //username
                $username = '1';
                if (isset($request['username'])) {
                    $username = $request['username'];
                }

                //comando de funcionalidad
                $comando = 'sin comando';
                if (isset($request['comando'])) {
                    $comando = $request['comando'];
                }




                /*
                 * Observacion personalizada - 20120919
                 */
                if ($this->observacion_list != false) {
                    $this->logMessage('[LIST sfQuery] Entro a personalizar observacion.');
                    $observacion = "'";

                    /*
                     * Se divide el string de la observacion por &
                     */
                    $keys = explode("&", $this->observacion_list);
                    foreach ($keys as $value) {

                        /*
                         * Valida si es variable de request
                         */
                        if (preg_match('/request/', $value)) {
                            $keys_req = explode("-", $value);

                            //valida variable en el request
                            if (isset($request[$keys_req[1]])) {

                                $value = $request[$keys_req[1]];
                            }
                        }

                        $observacion .= $value;
                    }

                    $observacion .= "'";
                } else {
                    $this->logMessage('[LIST sfQuery] No entro a personalizar observacion.');
                    /*
                     * construir observacion
                     */
                    $informe = 'sin especificar';
                    if (isset($this->filtro)) {
                        $informe = $this->filtro;

                        //observacion para el log
                        $observacion = "'Se consulto filtro: " . $informe . " desde la funcionalidad: " . $comando . "'";
                    } else {

                        //valida que sea menu de administracion para tabla log
                        if ($this->is_admin) {

                            $observacion = "'Se consulto tabla: " . $this->table_names[0] . " desde la funcionalidad: " . $comando . "'";
                        } else {


                            //sentencia sql
                            $sql = <<<EOD
select * from $tablaComandos where id_acceso = $modulo and cod_func = '$comando' 
EOD;

                            //ejecuta y obtiene el resultado del sql
//                        $resultado = CN_TABLE::executeOCI_SQL_List($sql, $usuarioERP, $claveERP);//otro usuario de la base de datos original
//                        $resultado = CN_TABLE::executeSQL($sql);
                            //realiza la conexion a la base de datos
                            $conn = Doctrine_Manager::connection();
                            //ejecuta el sql y obtiene todos los resultados
                            $resultado = $conn->execute($sql)->fetchAll();

                            if (count($resultado) > 0) {
                                $informe = $resultado[0]['ROTULO'];
                            }


                            //observacion para el log
                            $observacion = "'Se consulto informe: " . $informe . " desde la funcionalidad: " . $comando . "'";
                        }
                    }
                }


                /*
                 * Fin Variable LOG
                 */


                //llena los campos de las condiciones
                if (!is_null($this->table_field_conditions)) {
                    $cond_container = $this->poblateConditionValues($this->table_field_conditions, $request);
                }

                //llena los campos de las condiciones or
                if (!is_null($this->table_field_or_conditions)) {
                    $cond_or_container = $this->poblateConditionValues($this->table_field_or_conditions, $request);
                }

                //llena el campo de ordenamiento
                if (isset($request['_sortBy'])) {
                    $sortBy = $request['_sortBy'];
                    if (substr($sortBy, 0, 1) != '-') {
                        $sortBy .= ' ASC ';
                    } else {
                        $sortBy = substr($sortBy, 1);
                        $sortBy .= ' DESC ';
                    }
                }

                $tot_num_records = 0;
                $sum_res = array();

                /*
                 * Carga las filas por los paremetros de entrada
                 */
                $records = CN_TABLE::getAllWithFriendFields(
                                $this->table_names, $this->table_join_ids, $this->fields, $tot_num_records, $cond_container, $cond_or_container, $this->query_qualifier, $this->summatory, $sum_res, $this->fields_orderBy, $sortBy
                );

                //totales de filas y de consulta
                $this->logMessage('[sfQuery] record_count = ' . count($records));
                $this->logMessage('[sfQuery] total_record_count = ' . $tot_num_records);
                $this->totalRows = $tot_num_records;
                $this->startRow = $request['_startRow'];
                $this->endRow = $this->startRow + count($records);

                //Valida si se obtuvo valores en la consulta
                if (count($records) > 0) {

                    //Ip del servidor o equipode ingreso - 20190222
                    $ip_address = $_SERVER['REMOTE_ADDR'];
                    if (isset($request['ip_address'])) {
                        $ip_address = $request['ip_address'];
                    }

                    /*
                     * registro de consulta en tabla de log
                     */
                    //validar que solo sea al entrar 1 vez - click boton filtrar
                    if ($this->startRow == 0 && !$this->log_list) {
                        $this->logMessage("[sfQuery] Entro registro LOG.");
                        $sql = CN_TABLE::registroTableLog($id_tabla, $id_ope_bd, $id_mae_bd, $usuario, $username, $comando, $observacion, $ip_address);
                    } else {
                        $this->logMessage("[sfQuery] NO entro registro LOG.");
                    }



                    $this->list_data = $records;
                } else {
                    $this->list_data = array();
                }
            }//fin validacion filtro obligatorio
        } catch (Doctrine_Connection_Exception $e) {

            $mensaje = "[LIST sfQuery] ERROR Doctrine_Connection_Exception !!!";


            $this->list_errors = array(
                'Code' => $e->getCode(),
                'Message' => $e->getMessage(),
                'Line' => $e->getLine(),
                'Trace' => $e->getTraceAsString(),
                'mensaje' => $mensaje,
                'mensaje' => $mensaje,
                'operacion' => "LIST"
            );

            $this->logMessage($mensaje);
            $this->logMessage("status -1");
            $this->logMessage("Code " . $e->getCode());
            $this->logMessage("Message " . $e->getMessage());

            $this->status = $this->STATUS_FAILURE;
            $this->mensajeError = $mensaje;
            $this->list_data = array();
        } catch (Exception $e) {

            $mensaje = "[LIST sfQuery] ERROR Exception !!!";


            $this->list_errors = array(
                'Code' => $e->getCode(),
                'Message' => $e->getMessage(),
                'Line' => $e->getLine(),
                'Trace' => $e->getTraceAsString(),
                'mensaje' => $mensaje,
                'operacion' => "LIST"
            );

            $this->logMessage($mensaje);
            $this->logMessage("status -1");
            $this->logMessage("Code " . $e->getCode());
            $this->logMessage("Message " . $e->getMessage());

            $this->status = $this->STATUS_FAILURE;
            $this->mensajeError = $mensaje;
            $this->list_data = array();
        }
    }

    /**
     * Pobla los valores del request en un solo array
     *
     * @param array $conditions
     * @param sfWebRequest $request
     * @return array
     */
    private function poblateConditionValues($conditions, $request) {
        // Conditions
        // table_field_name
        // - ConditionName
        //   - Parameter
        $cond_cotainer = array();
        foreach ($conditions as $table_name => $fields) {
            $conds = array();
            foreach ($fields as $field => $expres) {
                $set_cond_field = array();
                foreach ($expres as $cond_name => $params) {
                    $set_params = array();
                    foreach ($params as $param_name) {
                        $param_value = $param_name;
                        if (is_string($param_name) && $param_name != '%' && strpos($param_name, 'field') === false) {
                            //$param_value = $request[$param_name];
                            //                            $this->logMessage($request[$param_name] . "----------------------------" . $param_name);
                            $param_value = sfAPIActions::extractIfBoolean($request[$param_name]); //cambio de valores booleanos - 20111031
                        }

                        /*
                         * Se agrega para manejar filtro: 
                         * si es: IS NOT NULL o IS NULL - 20120606
                         * 
                         * _filtroNull / para filtro de not null o null - type debe ser is - 20121001
                         */
//                        $this->logMessage("param_value = " . $param_value);
                        if ($param_name == '_filtroNull') {

                            $this->logMessage("Entro en si es: _filtroNull. Variable = " . $param_value);
                            if (isset($request[$param_name])) {
                                $valor = $set_params = $request[$param_name];
                            } else {
                                $valor = $set_params = null;
                            }
                        } elseif ($param_name == 'NOT NULL' || $param_name == 'NULL') {

                            $valor = $set_params = $param_name;
                            $this->logMessage("Entro en si es Variable = : IS NOT NULL o IS NULL." . $param_value);
                        } elseif ($param_value != null && $param_value != '' && $param_value != 'null') {
                            $this->logMessage("Entrada valores no nulos. Variable = " . $param_value);
                            $valor = $set_params[] = $param_value;
                        } else {
                            $this->logMessage("Entrada por Defecto. Variable = ");
                            $valor = $set_params = null;
                            /*
                             * filtro por valores numericos definidos en el actions - 20111104
                             */
                            if (is_numeric($param_name)) {
//                                $this->logMessage($request[$param_name] . "****************************" . $param_name);
                                $valor = $set_params[] = $param_name;
                            }
                            break;
                        }
//                        $this->logMessage(" Value: " . $param_name . " - " . $valor);
                    }
                    if ($set_params != null)
                        $set_cond_field[$cond_name] = $set_params;
                }
                if (count($set_cond_field) > 0)
                    $conds[$field] = $set_cond_field;
            }
            if (count($conds) > 0)
                $cond_cotainer[$table_name] = $conds;
        }
        if (count($cond_cotainer) == 0) {
            $cond_cotainer = null;
        }
        return $cond_cotainer;
    }

    /**
     * Obtener valores de la accion de sumatoria
     *
     * @param sfWebRequest $request
     */
    public function executeSum(sfWebRequest $request) {

        $cond_container = null;
        $cond_or_container = null;

        //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("--------------------------------------------------");
        foreach ($request->getGetParameters() as $key => $value) {
            $this->logMessage("request[$key] = $value");
        }
        $this->logMessage("---END Logging request");



        //validar errores de procedimiento
        try {


            //llena los campos de las condiciones
            if (!is_null($this->table_field_conditions)) {
                $cond_container = $this->poblateConditionValues($this->table_field_conditions, $request);
            }

            //llena los campos de las condiciones or
            if (!is_null($this->table_field_or_conditions)) {
                $cond_or_container = $this->poblateConditionValues($this->table_field_or_conditions, $request);
            }

            /*
             * Obtener consulta de sumatoria
             * segun los parametros y valores
             */
            $sum = CN_TABLE::getSum(
                            $this->table_names, $this->table_join_ids, $this->fields, $this->summatory_data, $cond_container, $cond_or_container, $this->query_qualifier
            );

            //Guardar valor en el archivo del log
            $this->logMessage('[sfQuery] sum = ' . count($sum));

            /*
             * Guardar valores obtenidos en el sql
             */
            foreach ($sum as $value) {
                foreach ($value as $key => $val) {
                    $this->logMessage("val[$key] = $val");
                }
            }

            //Valida si se obtuvo valores en la consulta
            if (count($sum) > 0) {
                $this->list_data = $sum;
            } else {
                $this->list_data = array();
            }
        } catch (Doctrine_Connection_Exception $e) {

            $mensaje = "[SUM sfQuery] ERROR Doctrine_Connection_Exception !!!";


            $this->list_errors = array(
                'Code' => $e->getCode(),
                'Message' => $e->getMessage(),
                'Line' => $e->getLine(),
                'Trace' => $e->getTraceAsString(),
                'mensaje' => $mensaje,
                'operacion' => "SUM"
            );

            $this->logMessage($mensaje);
            $this->logMessage("status -1");
            $this->logMessage("Code " . $e->getCode());
            $this->logMessage("Message " . $e->getMessage());

            $this->status = $this->STATUS_FAILURE;
            $this->mensajeError = $mensaje;
            $this->list_data = array();
        } catch (Exception $e) {

            $mensaje = "[SUM sfQuery] ERROR Exception !!!";


            $this->list_errors = array(
                'Code' => $e->getCode(),
                'Message' => $e->getMessage(),
                'Line' => $e->getLine(),
                'Trace' => $e->getTraceAsString(),
                'mensaje' => $mensaje,
                'operacion' => "SUM"
            );

            $this->logMessage($mensaje);
            $this->logMessage("status -1");
            $this->logMessage("Code " . $e->getCode());
            $this->logMessage("Message " . $e->getMessage());

            $this->status = $this->STATUS_FAILURE;
            $this->mensajeError = $mensaje;
            $this->list_data = array();
        }
    }

    /**
     * Obtener saldos por los parametros de entrada
     *
     * @param sfWebRequest $request
     */
    public function executeSaldo(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("---END Logging request");


        //validar errores de procedimiento
        try {
            
        } catch (Doctrine_Connection_Exception $e) {

            $mensaje = "[SALDO sfQuery] ERROR Doctrine_Connection_Exception !!!";


            $this->list_errors = array(
                'Code' => $e->getCode(),
                'Message' => $e->getMessage(),
                'Line' => $e->getLine(),
                'Trace' => $e->getTraceAsString(),
                'mensaje' => $mensaje,
                'operacion' => "SALDO"
            );

            $this->logMessage($mensaje);
            $this->logMessage("status -1");
            $this->logMessage("Code " . $e->getCode());
            $this->logMessage("Message " . $e->getMessage());

            $this->status = $this->STATUS_FAILURE;
            $this->mensajeError = $mensaje;
            $this->list_data = array();
        } catch (Exception $e) {

            $mensaje = "[SALDO sfQuery] ERROR Exception !!!";


            $this->list_errors = array(
                'Code' => $e->getCode(),
                'Message' => $e->getMessage(),
                'Line' => $e->getLine(),
                'Trace' => $e->getTraceAsString(),
                'mensaje' => $mensaje,
                'operacion' => "SALDO"
            );

            $this->logMessage($mensaje);
            $this->logMessage("status -1");
            $this->logMessage("Code " . $e->getCode());
            $this->logMessage("Message " . $e->getMessage());

            $this->status = $this->STATUS_FAILURE;
            $this->mensajeError = $mensaje;
            $this->list_data = array();
        }
    }

    //------------FUNCIONES CRUD

    /**
     *
     * @param sfWebRequest $request
     */
    //  public function executeRemove(sfWebRequest $request) {
//
    //     if (!is_null($this->id_name) && !is_null($this->table_name) && $this->has_id_cia) {
//
    //         parent::executeRemove($request);
    //      }
    //}

    /**
     *
     * @param sfWebRequest $request
     */
    //  public function executeAdd(sfWebRequest $request) {
//
    //     if (!is_null($this->id_names) && !is_null($this->field_names) && !is_null($this->table_name) && $this->has_id_cia) {
//
    //          parent::executeAdd($request);
    //     }
    //}

    /**
     *
     * @param sfWebRequest $request
     */
    //  public function executeUpdate(sfWebRequest $request) {
//
//
    //      if (!is_null($this->id_names) && !is_null($this->field_names) && !is_null($this->table_name)) {
//
    //        parent::executeUpdate($request);
    //    }
    //}
}

?>
