public function crearTablaIndicador(FichaTecnica $fichaTecnica, $duracion = 10) { $ahora = new \DateTime("now"); if ($fichaTecnica->getUpdatedAt() != '') { $ultimo_calculo = $fichaTecnica->getUpdatedAt()->getTimestamp(); $diff_minutos = ($ahora->getTimestamp() - $ultimo_calculo) / 60; if ($diff_minutos <= $duracion) { return; } } $em = $this->getEntityManager(); $util = new \MINSAL\IndicadoresBundle\Util\Util(); $campos = str_replace("'", '', $fichaTecnica->getCamposIndicador()); $nombre_indicador = $util->slug($fichaTecnica->getNombre()); $tablas_variables = array(); $sql = ''; // Crear las tablas para cada variable foreach ($fichaTecnica->getVariables() as $variable) { //Recuperar la información de los campos para crear la tabla $tabla = strtolower($variable->getIniciales()); $sql .= 'DROP TABLE IF EXISTS tmp_ind_' . $nombre_indicador . '; '; $sql .= 'CREATE TEMP TABLE IF NOT EXISTS ' . $tabla . '('; foreach ($variable->getOrigenDatos()->getCampos() as $campo) { $sql .= $campo->getSignificado()->getCodigo() . ' ' . $campo->getTipoCampo()->getCodigo() . ', '; } $sql = trim($sql, ', ') . ');'; //Llenar la tabla con los valores del hstore $sql .= "INSERT INTO {$tabla}\n SELECT (populate_record(null::{$tabla}, datos)).* \n FROM fila_origen_dato \n WHERE id_origen_dato = " . $variable->getOrigenDatos()->getId() . ' ;'; //Obtener solo los datos que se pueden procesar en el indicador $sql .= "SELECT {$campos}, SUM(calculo::numeric) AS " . $tabla . "\n INTO TEMP {$tabla}" . "_var\n FROM {$tabla} \n GROUP BY {$campos} \n HAVING SUM(calculo::numeric) > 0\n ;"; $tablas_variables[] = $tabla; } $sql .= 'SELECT ' . $campos . ',' . implode(',', $tablas_variables) . " INTO tmp_ind_" . $nombre_indicador . " FROM " . array_shift($tablas_variables) . '_var '; foreach ($tablas_variables as $tabla) { $sql .= " INNER JOIN " . $tabla . "_var USING ({$campos}) "; } $fichaTecnica->setUpdatedAt($ahora); $em->persist($fichaTecnica); $em->flush(); $em->getConnection()->exec($sql); }
/** * @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(); } }