public function calcularIndicador(FichaTecnica $fichaTecnica, $dimension, $filtro_registros = null)
 {
     $util = new \MINSAL\IndicadoresBundle\Util\Util();
     $formula = str_replace(array('{', '}'), array('SUM(', ')'), $fichaTecnica->getFormula());
     $nombre_indicador = $util->slug($fichaTecnica->getNombre());
     $tabla_indicador = 'tmp_ind_' . $nombre_indicador;
     $sql = "SELECT {$dimension} as category, round(({$formula})::numeric,2) as measure\n            FROM {$tabla_indicador} ";
     if ($filtro_registros != null) {
         $sql .= ' WHERE 1=1 ';
         foreach ($filtro_registros as $campo => $valor) {
             $sql .= " AND {$campo} = '{$valor}' ";
         }
     }
     $sql .= "\n            GROUP BY {$dimension} \n            ORDER BY {$dimension}";
     return $this->getEntityManager()->getConnection()->executeQuery($sql)->fetchAll();
 }
 /**
  * @Route("/indicador/dimensiones/{id}", name="indicador_dimensiones", options={"expose"=true})
  */
 public function getDimensiones(FichaTecnica $fichaTec)
 {
     $resp = array();
     $em = $this->getDoctrine()->getManager();
     if ($fichaTec) {
         $resp['nombre_indicador'] = $fichaTec->getNombre();
         $resp['id_indicador'] = $fichaTec->getId();
         $resp['unidad_medida'] = $fichaTec->getUnidadMedida();
         if ($fichaTec->getUpdatedAt() != "") {
             $resp["origen_dato_actualizacion"] = date('d/m/Y H:i:s', $fichaTec->getUpdatedAt()->getTimestamp());
         }
         if ($fichaTec->getCamposIndicador() != '') {
             $campos = explode(',', str_replace(array("'", ' '), array('', ''), $fichaTec->getCamposIndicador()));
         } else {
             $campos = array();
         }
         $dimensiones = array();
         foreach ($campos as $campo) {
             $significado = $em->getRepository('IndicadoresBundle:SignificadoCampo')->findOneByCodigo($campo);
             if (count($significado->getTiposGraficosArray()) > 0) {
                 $dimensiones[$significado->getCodigo()]['descripcion'] = ucfirst(preg_replace('/^Identificador /i', '', $significado->getDescripcion()));
                 $dimensiones[$significado->getCodigo()]['escala'] = $significado->getEscala();
                 $dimensiones[$significado->getCodigo()]['origenX'] = $significado->getOrigenX();
                 $dimensiones[$significado->getCodigo()]['origenY'] = $significado->getOrigenY();
                 $dimensiones[$significado->getCodigo()]['graficos'] = $significado->getTiposGraficosArray();
             }
         }
         $rangos_alertas_aux = array();
         foreach ($fichaTec->getAlertas() as $k => $rango) {
             $rangos_alertas_aux[$rango->getLimiteSuperior()]['limite_sup'] = $rango->getLimiteSuperior();
             $rangos_alertas_aux[$rango->getLimiteSuperior()]['limite_inf'] = $rango->getLimiteInferior();
             $rangos_alertas_aux[$rango->getLimiteSuperior()]['color'] = $rango->getColor()->getCodigo();
             $rangos_alertas_aux[$rango->getLimiteSuperior()]['comentario'] = $rango->getComentario();
         }
         ksort($rangos_alertas_aux);
         $rangos_alertas = array();
         foreach ($rangos_alertas_aux as $rango) {
             $rangos_alertas[] = $rango;
         }
         $resp['rangos'] = $rangos_alertas;
         $resp['formula'] = $fichaTec->getFormula();
         $resp['meta'] = $fichaTec->getMeta();
         $resp['dimensiones'] = $dimensiones;
         //Verificar que se tiene la más antigua de las últimas lecturas de los orígenes
         //de datos del indicador
         $ultima_lectura = new \DateTime("NOW");
         foreach ($fichaTec->getVariables() as $var) {
             $fecha_lectura = $em->getRepository('IndicadoresBundle:OrigenDatos')->getUltimaActualizacion($var->getOrigenDatos());
             if ($fecha_lectura < $ultima_lectura) {
                 $ultima_lectura = $fecha_lectura;
             }
             $conexion = "Excel o csv";
             foreach ($var->getOrigenDatos()->getConexiones() as $od) {
                 $conexion = $od->__toString();
             }
             $fuente = null;
             if (method_exists($var->getIdFuenteDato(), '__toString')) {
                 $fuente = $var->getIdFuenteDato()->__toString();
             }
             $responsable = null;
             if (method_exists($var->getIdResponsableDato(), '__toString')) {
                 $responsable = $var->getIdResponsableDato()->__toString();
             }
             $resp["origen_dato_"][] = array("origen_dato_nombre" => $var->getNombre(), "origen_dato_confiabilidad" => $var->getConfiabilidad(), "origen_dato_fuente" => $fuente, "origen_dato_responsable" => $responsable, "origen_dato_origen" => $var->getOrigenDatos()->getNombre(), "origen_dato_conexion" => $conexion);
         }
         $fichaTec->setUltimaLectura(new \DateTime($ultima_lectura));
         $em->flush();
         $resp['ultima_lectura'] = date('d/m/Y H:i:s', $fichaTec->getUltimaLectura()->getTimestamp());
         $resp['resultado'] = 'ok';
     } else {
         $resp['resultado'] = 'error';
     }
     $response = new Response(json_encode($resp));
     if ($this->get('kernel')->getEnvironment() != 'dev') {
         $response->setMaxAge($this->container->getParameter('indicador_cache_consulta'));
     }
     return $response;
 }
 public function crearPentahoCDA(FichaTecnica $fichaTecnica)
 {
     //crear archivo solo en caso que no exista.
     $CDAFile = $this->getConfigurationPool()->getContainer()->getParameter('carpeta_pentaho_cda') . "indicador" . $fichaTecnica->getId() . ".cda";
     if (!file_exists($CDAFile)) {
         $em = $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager();
         $util = new \MINSAL\IndicadoresBundle\Util\Util();
         $campos = explode(",", str_replace("'", '', $fichaTecnica->getCamposIndicador()));
         $campos = array_map('trim', $campos);
         $formula = str_replace(' ', '', $fichaTecnica->getFormula());
         $tabla = "tmp_ind_" . $util->slug($fichaTecnica->getNombre());
         $queries = $this->crearPentahoCDAQueries($campos, $tabla, $formula);
         $this->crearPentahoCDAArchivo($queries, $fichaTecnica->getId());
         $em->flush();
     }
 }
 public function calcularIndicador(FichaTecnica $fichaTecnica, $dimension, $filtro_registros = null, $ver_sql = false)
 {
     $util = new \MINSAL\IndicadoresBundle\Util\Util();
     $acumulado = $fichaTecnica->getEsAcumulado();
     $formula = str_replace(' ', '', strtolower($fichaTecnica->getFormula()));
     //Recuperar las variables
     $variables = array();
     preg_match_all('/\\{[a-z0-9\\_]{1,}\\}/', strtolower($formula), $variables, PREG_SET_ORDER);
     $denominador = explode('/', $fichaTecnica->getFormula());
     $evitar_div_0 = '';
     $variables_d = array();
     if (count($denominador) > 1) {
         preg_match('/\\{.{1,}\\}/', $denominador[1], $variables_d);
         if (count($variables_d) > 0) {
             $var_d = strtolower(str_replace(array('{', '}'), array('(', ')'), array_shift($variables_d)));
         }
         $evitar_div_0 = 'AND ' . $var_d . ' > 0';
     }
     // Formar la cadena con las variables para ponerlas en la consulta
     $variables_query = '';
     foreach ($variables as $var) {
         $oper_ = explode($var[0], $formula);
         $tieneOperadores = preg_match('/([A-Za-z]+)\\($/', $oper_[0], $coincidencias, PREG_OFFSET_CAPTURE);
         $oper = $tieneOperadores ? $coincidencias[1][0] : 'SUM';
         $v = str_replace(array('{', '}'), array('', ''), $var[0]);
         $formula = str_replace($var[0], ($oper == 'SUM' ? $oper : '') . str_replace(array('{', '}'), array('(', ')'), $var[0]), $formula);
         $variables_query .= " {$oper}({$v}) as {$v}, ";
     }
     $variables_query = trim($variables_query, ', ');
     $nombre_indicador = $util->slug($fichaTecnica->getNombre());
     $tabla_indicador = 'tmp_ind_' . $nombre_indicador;
     //Verificar si es un catálogo
     $rel_catalogo = '';
     $otros_campos = '';
     $grupo_extra = '';
     $significado = $this->getEntityManager()->getRepository('IndicadoresBundle:SignificadoCampo')->findOneBy(array('codigo' => $dimension));
     $catalogo = $significado->getCatalogo();
     if ($catalogo != '') {
         $rel_catalogo = " INNER JOIN  {$catalogo}  B ON (A.{$dimension}::text = B.id::text) ";
         $dimension = 'B.descripcion';
         $otros_campos = ' B.id AS id_category, ';
         $grupo_extra = ', B.id ';
     }
     $filtros = '';
     if ($filtro_registros != null) {
         foreach ($filtro_registros as $campo => $valor) {
             //Si el filtro es un catálogo, buscar su id correspondiente
             $significado = $this->getEntityManager()->getRepository('IndicadoresBundle:SignificadoCampo')->findOneBy(array('codigo' => $campo));
             $catalogo = $significado->getCatalogo();
             $sql_ctl = '';
             if ($catalogo != '') {
                 $sql_ctl = "SELECT id FROM {$catalogo} WHERE descripcion ='{$valor}'";
                 $reg = $this->getEntityManager()->getConnection()->executeQuery($sql_ctl)->fetch();
                 $valor = $reg['id'];
             }
             $filtros .= " AND A." . $campo . " = '{$valor}' ";
         }
     }
     if ($acumulado) {
         $em = $this->getEntityManager();
         $var_n = array_pop(str_replace(array('{', '}'), array('', ''), $variables[0]));
         $var_d = array_pop(str_replace(array('{', '}'), array('', ''), $variables[1]));
         $filtros_ = str_replace('A.', 'AA.', $filtros_);
         //leer la primera fila para determinar el tipo de dato de la dimensión actual
         $sql2 = "SELECT {$dimension} FROM {$tabla_indicador} LIMIT 1";
         $operador = is_numeric(array_pop($em->getConnection()->executeQuery($sql2)->fetch())) ? '<=' : '=';
         $formula = str_replace(array('SUM(' . $var_n . ')', 'SUM(' . $var_d . ')'), array("(SELECT SUM(AA.{$var_n}) FROM {$tabla_indicador} AA WHERE AA.{$dimension} {$operador} A.{$dimension} {$filtros_})", "(SELECT SUM(DISTINCT AA.{$var_d}) FROM {$tabla_indicador} AA WHERE AA.{$dimension} {$operador} A.{$dimension} {$filtros_})"), $formula);
         $variables_query = str_replace(array('SUM(' . $var_n . ')', 'SUM(' . $var_d . ')'), array("(SELECT SUM(AA.{$var_n}) FROM {$tabla_indicador} AA WHERE AA.{$dimension} {$operador} A.{$dimension} {$filtros_})", "(SELECT SUM(DISTINCT AA.{$var_d}) FROM {$tabla_indicador} AA WHERE AA.{$dimension} {$operador} A.{$dimension} {$filtros_})"), $variables_query);
     }
     $sql = "SELECT {$dimension} AS category, {$otros_campos} {$variables_query}, round(({$formula})::numeric,2) AS measure\n            FROM {$tabla_indicador} A" . $rel_catalogo;
     $sql .= ' WHERE 1=1 ' . $evitar_div_0 . ' ' . $filtros;
     $sql .= "\n            GROUP BY {$dimension} {$grupo_extra}";
     $sql .= $acumulado ? '' : "HAVING (({$formula})::numeric) > 0";
     $sql .= "ORDER BY {$dimension}";
     try {
         if ($ver_sql == true) {
             return $sql;
         } else {
             return $this->getEntityManager()->getConnection()->executeQuery($sql)->fetchAll();
         }
     } catch (\PDOException $e) {
         return $e->getMessage();
     } catch (\Doctrine\DBAL\DBALException $e) {
         return $e->getMessage();
     }
 }