/**
  * Obtener los datos del indicador sin aplicar la fórmula ni filtros
  * @param integer $fichaTec
  * @param string $dimension
  * @Get("/rest-service/data/{id}", options={"expose"=true})
  * @Rest\View
  */
 public function getDatosIndicadorAction(FichaTecnica $fichaTec)
 {
     $response = new Response();
     // crea una respuesta con una cabecera ETag y Last-Modified
     // para determinar si se debe calcular el indicador u obtener de la caché
     // para el modo de desarrollo (dev) nunca tomar de caché
     $response->setETag($fichaTec->getId() . '_datos');
     $response->setLastModified($this->get('kernel')->getEnvironment() == 'dev' ? new \DateTime('NOW') : $fichaTec->getUltimaLectura());
     // verifica que la respuesta no se ha modificado para la petición dada
     if ($response->isNotModified($this->getRequest())) {
         // devuelve inmediatamente la respuesta 304 de la caché
         return $response;
     } else {
         $resp = array();
         $em = $this->getDoctrine()->getManager();
         $fichaRepository = $em->getRepository('IndicadoresBundle:FichaTecnica');
         $fichaRepository->crearIndicador($fichaTec);
         $resp = $fichaRepository->getDatosIndicador($fichaTec);
         $respj = json_encode($resp);
         $response->setContent($respj);
         return $response;
     }
 }
 /**
  * @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 crearIndicador(FichaTecnica $fichaTecnica, $dimension = null, $filtros = null)
 {
     $em = $this->getEntityManager();
     $ahora = new \DateTime('NOW');
     $util = new \MINSAL\IndicadoresBundle\Util\Util();
     $nombre_indicador = $util->slug($fichaTecnica->getNombre());
     $formula = strtoupper($fichaTecnica->getFormula());
     //Verificar si existe la tabla
     $existe = true;
     $acumulado = $fichaTecnica->getEsAcumulado();
     try {
         $em->getConnection()->query("select count(*) from tmp_ind_{$nombre_indicador}");
     } catch (\Doctrine\DBAL\DBALException $e) {
         $existe = false;
     }
     if ($fichaTecnica->getUpdatedAt() != '' and $fichaTecnica->getUltimaLectura() != '' and $existe == true) {
         if ($fichaTecnica->getUltimaLectura() < $fichaTecnica->getUpdatedAt()) {
             return true;
         }
     }
     $campos = str_replace("'", '', $fichaTecnica->getCamposIndicador());
     $tablas_variables = array();
     $sql = 'DROP TABLE IF EXISTS tmp_ind_' . $nombre_indicador . '; ';
     // Crear las tablas para cada variable
     foreach ($fichaTecnica->getVariables() as $variable) {
         //Recuperar la información de los campos para crear la tabla
         $origen = $variable->getOrigenDatos();
         $diccionarios = array();
         // Si es pivote crear las tablas para los origenes relacionados
         if ($origen->getEsPivote()) {
             $campos_pivote = explode(",", str_replace("'", '', $origen->getCamposFusionados()));
             $pivote = array();
             $campos_regulares = array();
             $tablas_piv = array();
             foreach ($origen->getFusiones() as $or) {
                 $or_id = $or->getId();
                 $sql .= " CREATE TEMP TABLE IF NOT EXISTS od_{$or_id} ( ";
                 foreach ($or->getCampos() as $campo) {
                     $tipo = $campo->getTipoCampo()->getCodigo();
                     $sig = $campo->getSignificado()->getCodigo();
                     $sql .= $sig . ' ' . $tipo . ', ';
                     if (in_array($sig, $campos_pivote)) {
                         $pivote[$sig] = $tipo;
                     } else {
                         $campos_regulares[$sig] = $tipo;
                     }
                 }
                 $sql = trim($sql, ', ');
                 $tablas_piv[] = 'od_' . $or_id;
                 $campos_piv = array_merge($pivote, $campos_regulares);
                 $sql .= ' ); ';
                 $sql .= "INSERT INTO od_{$or_id}\n                    SELECT (populate_record(null::od_{$or_id}, datos)).*\n                    FROM fila_origen_dato\n                        WHERE id_origen_dato = '{$or_id}'\n                    ;";
             }
         }
         //Crear la estructura de la tabla asociada a la variable
         $tabla = strtolower($variable->getIniciales());
         $sql .= ' CREATE TEMP TABLE IF NOT EXISTS ' . $tabla . '(';
         if ($origen->getEsFusionado()) {
             $significados = explode(",", str_replace("'", '', $origen->getCamposFusionados()));
             //Los tipos de campos sacarlos de uno de los orígenes de datos que ha sido fusionado
             $fusionados = $origen->getFusiones();
             $fusionado = $fusionados[0];
             $tipos = array();
             foreach ($fusionado->getCampos() as $campo) {
                 $tipos[$campo->getSignificado()->getCodigo()] = $campo->getTipoCampo()->getCodigo();
             }
             foreach ($significados as $campo) {
                 $sql .= $campo . ' ' . $tipos[$campo] . ', ';
             }
             $sql .= 'calculo numeric, ';
         } elseif ($origen->getEsPivote()) {
             foreach ($campos_piv as $campo => $tipo) {
                 $sql .= $campo . ' ' . $tipo . ', ';
             }
         } else {
             foreach ($origen->getCampos() as $campo) {
                 $sql .= $campo->getSignificado()->getCodigo() . ' ' . $campo->getTipoCampo()->getCodigo() . ', ';
                 if ($campo->getDiccionario() != null) {
                     $diccionarios[$campo->getSignificado()->getCodigo()] = $campo->getDiccionario()->getId();
                 }
             }
         }
         $sql = trim($sql, ', ') . ');';
         // Recuperar los datos desde los orígenes
         //Llenar la tabla con los valores del hstore
         if ($origen->getEsPivote()) {
             $tabla1 = array_shift($tablas_piv);
             $sql .= " INSERT INTO {$tabla} SELECT " . implode(', ', array_keys($campos_piv)) . " FROM {$tabla1} ";
             foreach ($tablas_piv as $t) {
                 $sql .= " FULL OUTER JOIN {$t} USING (" . implode(', ', array_keys($pivote)) . ') ';
             }
             $sql .= '; ';
         } else {
             // Si es fusionado recuperar los orígenes que están contenidos
             $origenes = array();
             if ($origen->getEsFusionado()) {
                 foreach ($origen->getFusiones() as $of) {
                     $origenes[] = $of->getId();
                 }
             } else {
                 $origenes[] = $origen->getId();
             }
             $sql .= "INSERT INTO {$tabla}\n                    SELECT (populate_record(null::{$tabla}, datos)).*\n                    FROM fila_origen_dato\n                        WHERE id_origen_dato IN (" . implode(',', $origenes) . ")\n                    ;";
         }
         //Obtener los campos que son calculados
         $campos_calculados = array();
         foreach ($origen->getCamposCalculados() as $campo) {
             $campos_calculados[$campo->getSignificado()->getCodigo()] = str_replace(array('{', '}'), '', $campo->getFormula()) . ' AS ' . $campo->getSignificado()->getCodigo();
         }
         $campos_calculados_nombre = '';
         if (count($campos_calculados) > 0) {
             //Quitar los campos calculados del listado campos del indicador sino da error
             $campos_aux = explode(',', str_replace(' ', '', $campos));
             $campos = implode(',', array_diff($campos_aux, array_keys($campos_calculados)));
             $campos_calculados_nombre = ', ' . implode(', ', array_keys($campos_calculados));
             $campos_calculados = ', ' . implode(', ', $campos_calculados);
         } else {
             $campos_calculados = '';
         }
         //Obtener solo los datos que se pueden procesar en el indicador
         $sql .= "DROP TABLE IF EXISTS {$tabla}" . "_var; ";
         //Obtener el operador de la variable
         $oper_ = explode('{' . $variable->getIniciales() . '}', str_replace(' ', '', $formula));
         $tieneOperadores = preg_match('/([A-Z]+)\\($/', $oper_[0], $coincidencias, PREG_OFFSET_CAPTURE);
         $oper = $tieneOperadores ? $coincidencias[1][0] : 'SUM';
         $sql .= "SELECT  {$campos}, {$oper}(calculo::numeric) AS  {$tabla} {$campos_calculados}\n                INTO  TEMP {$tabla}" . "_var\n                FROM {$tabla}\n                GROUP BY {$campos} {$campos_calculados_nombre}\n                HAVING  {$oper}(calculo::numeric) > 0\n                    ;";
         //aplicar transformaciones si las hubieran
         foreach ($diccionarios as $campo => $diccionario) {
             $sql .= "\n                        UPDATE {$tabla}" . "_var SET {$campo} = regla.transformacion\n                            FROM regla_transformacion AS regla\n                            WHERE {$tabla}" . "_var.{$campo} = regla.limite_inferior\n                                AND id_diccionario = {$diccionario}\n                    ;";
         }
         $tablas_variables[] = $tabla;
     }
     try {
         $sql .= $this->crearTablaIndicador($fichaTecnica, $tablas_variables);
         $em->getConnection()->exec($sql);
         $fichaTecnica->setUpdatedAt($ahora);
         $em->persist($fichaTecnica);
         $em->flush();
     } catch (\PDOException $e) {
         return $e->getMessage();
     }
 }