src/Repository/Cliente/Dados/CalculoRepository.php line 1258

Open in your IDE?
  1. <?php
  2. namespace App\Repository\Cliente\Dados;
  3. use App\Entity\Cliente\Dados\Calculo;
  4. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  5. use Doctrine\DBAL\Driver\ResultStatement;
  6. use Doctrine\DBAL\ParameterType;
  7. use Doctrine\Persistence\ManagerRegistry;
  8. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  9. use App\Entity\Cliente\Modelagem\Modelagem;
  10. use DateTime;
  11. use Doctrine\DBAL\Result;
  12. /**
  13.  * @method null|Calculo find($id, $lockMode = null, $lockVersion = null)
  14.  * @method null|Calculo findOneBy(array $criteria, array $orderBy = null)
  15.  * @method Calculo[]    findAll()
  16.  * @method Calculo[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  17.  */
  18. class CalculoRepository extends ServiceEntityRepository
  19. {
  20.     /**
  21.      * @var SessionInterface
  22.      */
  23.     private $session;
  24.     public function __construct(ManagerRegistry $registrySessionInterface $session)
  25.     {
  26.         $this->session $session;
  27.         parent::__construct($registryCalculo::class);
  28.     }
  29.     /**
  30.      * @author Guilherme Arduino <guilherme.barlatti@2im.com.br>
  31.      *
  32.      * @return ResultStatement
  33.      */
  34.     public function getDesempenhoIndicadores(array $programa, array $periodos, array $buscastring $gestor_permissoes ''): ? ResultStatement
  35.     {
  36.         $sql sprintf(
  37.             'SELECT
  38.                  id_dominio
  39.                 ,nome_dominio
  40.                 ,md.ordem
  41.                 ,Jsonb_Agg(d) indicadores
  42.             FROM(
  43.                 SELECT
  44.                      id_indicador
  45.                     ,id_dominio
  46.                     ,nome_indicador
  47.                     ,nome_dominio
  48.                     ,total_indicador
  49.                     ,Jsonb_Agg(qtd_avaliados ORDER BY performance ASC) contagem
  50.                     ,Jsonb_Agg(performance   ORDER BY performance ASC) performance
  51.                     ,Jsonb_Agg(porcentagem   ORDER BY performance ASC) porcentagem
  52.                 FROM(
  53.                     SELECT
  54.                          id_indicador
  55.                         ,nome_indicador
  56.                         ,id_dominio
  57.                         ,nome_dominio
  58.                         ,performance
  59.                         ,contagem
  60.                         ,total_indicador
  61.                         ,COUNT(DISTINCT id_avaliado) qtd_avaliados
  62.                         ,CASE WHEN total_indicador > 0 THEN ROUND((SUM(contagem) / SUM(total_indicador)) * 100, 2) ELSE 0 END porcentagem
  63.                     FROM(
  64.                         SELECT
  65.                              id_avaliado
  66.                             ,id_indicador
  67.                             ,nome_indicador
  68.                             ,id_dominio
  69.                             ,nome_dominio
  70.                             ,performance
  71.                             ,COUNT(1) OVER(PARTITION BY id_indicador, performance) contagem
  72.                             ,COUNT(1) FILTER(WHERE id_avaliado IS NOT NULL) OVER(PARTITION BY id_indicador) total_indicador
  73.                         FROM (
  74.                             SELECT
  75.                                  mi.id_indicador
  76.                                 ,mi.titulo nome_indicador
  77.                                 ,md.id_dominio
  78.                                 ,md.titulo nome_dominio
  79.                                 ,id_programa
  80.                                 ,i.id_avaliado
  81.                                 ,ms.id_grupo
  82.                                 ,performance
  83.                             FROM
  84.                                 modelagem.scorecard ms
  85.                                 JOIN modelagem.indicador mi USING(id_indicador)
  86.                                 JOIN modelagem.dominio md USING(id_dominio)
  87.                                 JOIN modelagem.modelagem mm USING(id_modelagem)
  88.                                 LEFT JOIN (
  89.                                     SELECT
  90.                                          id_avaliado
  91.                                         ,id_indicador
  92.                                         ,ROUND(performance, 2) performance
  93.                                         ,id_grupo
  94.                                     FROM
  95.                                         dados.calculo
  96.                                     WHERE TRUE
  97.                                     %s %s %s
  98.                                 ) i USING(id_indicador, id_grupo)
  99.                             WHERE TRUE %s %s
  100.                             ORDER BY 1
  101.                         ) a
  102.                         WHERE TRUE %s
  103.                     ) b
  104.                     GROUP BY 1,2,3,4,5,6,7
  105.                     ORDER BY 3,1,4
  106.                 ) c
  107.                 GROUP BY 1,2,3,4,5
  108.             ) d
  109.             JOIN modelagem.dominio md USING(id_dominio)
  110.             GROUP BY 1,2,3
  111.             ORDER BY 3',
  112.             $periodos['where'],
  113.             $programa['where'],
  114.             $busca[0] ?? '',
  115.             $programa['where'],
  116.             $busca[1] ?? '',
  117.             $gestor_permissoes
  118.         );
  119.         return $this->_em->getConnection()->executeQuery($sql);
  120.     }
  121.     /**
  122.      * @return ResultStatement
  123.      */
  124.     public function getIndicadoresContagemPorDesempenho(array $programa, array $periodos, array $buscastring $gestor_permissoes ''): ? ResultStatement
  125.     {
  126.         $sql sprintf("SELECT
  127.                             id_dominio,
  128.                             nome_dominio,
  129.                             Jsonb_Agg(e) indicadores
  130.                         FROM (
  131.                             SELECT
  132.                                 id_indicador,
  133.                                 id_dominio,
  134.                                 nome_indicador,
  135.                                 nome_dominio,
  136.                                 total_indicador,
  137.                                 Jsonb_Agg(contagem     ORDER BY performance ASC) contagem,
  138.                                 Jsonb_Agg(performance  ORDER BY performance ASC) performance,
  139.                                 Jsonb_Agg(porcentagem  ORDER BY performance ASC) porcentagem
  140.                             FROM (
  141.                                 SELECT
  142.                                     id_indicador,
  143.                                     id_dominio,
  144.                                     nome_indicador,
  145.                                     nome_dominio,
  146.                                     total_indicador,
  147.                                     contagem,
  148.                                     performance,
  149.                                     CASE
  150.                                         WHEN total_indicador > 0 THEN ROUND( (contagem::numeric * 100) / total_indicador::numeric, 3)
  151.                                         ELSE 0
  152.                                     END porcentagem
  153.                                 FROM (
  154.                                     SELECT
  155.                                         b.*,
  156.                                         COUNT(1) OVER(PARTITION BY id_indicador, performance) contagem,
  157.                                         COUNT(1) OVER(PARTITION BY id_indicador) total_indicador
  158.                                     FROM (
  159.                                         SELECT
  160.                                             a.*,
  161.                                             CASE
  162.                                                 WHEN performance = 100 THEN 100.00
  163.                                                 WHEN performance BETWEEN 90 AND 99.99 THEN 90.00
  164.                                                 WHEN performance BETWEEN 80 AND 89.99 THEN 80.00
  165.                                                 WHEN performance BETWEEN 70 AND 79.99 THEN 70.00
  166.                                                 WHEN performance BETWEEN 60 AND 69.99 THEN 60.00
  167.                                                 WHEN performance BETWEEN 50 AND 59.99 THEN 50.00
  168.                                                 WHEN performance BETWEEN 40 AND 49.99 THEN 40.00
  169.                                                 WHEN performance BETWEEN 30 AND 39.99 THEN 30.00
  170.                                                 WHEN performance BETWEEN 20 AND 29.99 THEN 20.00
  171.                                                 WHEN performance BETWEEN 10 AND 19.99 THEN 10.00
  172.                                                 WHEN performance BETWEEN 0 AND 9.99 THEN 0.00
  173.                                                 ELSE performance
  174.                                             END performance
  175.                                         FROM (
  176.                                             SELECT
  177.                                                 DISTINCT id_avaliado,
  178.                                                 nome_avaliado,
  179.                                                 id_indicador,
  180.                                                 nome_indicador,
  181.                                                 id_dominio,
  182.                                                 nome_dominio,
  183.                                                 id_modelagem,
  184.                                                 id_programa,
  185.                                                 id_grupo,
  186.                                                 periodo
  187.                                             FROM modelagem.scorecard_avaliados
  188.                                             JOIN LATERAL (
  189.                                                 SELECT generate_periodo periodo FROM generate_periodo(%s,%s)
  190.                                             ) p ON periodo BETWEEN avaliacao_inicio AND avaliacao_fim
  191.                                             JOIN (
  192.                                                 SELECT DISTINCT id_avaliado FROM dados.calculo c WHERE Concat(c.periodo->>'ano', c.periodo->>'periodo')::integer BETWEEN %s AND %s AND id_programa = %s AND id_modelagem = %s
  193.                                             ) av USING(id_avaliado)
  194.                                                WHERE TRUE
  195.                                                 %s %s %s %s
  196.                                         ) a
  197.                                         LEFT JOIN dados.calculo c ON a.id_avaliado = c.id_avaliado AND a.id_indicador = c.id_indicador AND a.periodo::text = Concat(c.periodo->>'ano', c.periodo->>'periodo') AND a.id_programa = c.id_programa AND a.id_modelagem = c.id_modelagem
  198.                                         WHERE TRUE AND c.id_modelagem = %s AND c.id_programa = %s
  199.                                         ORDER BY 1,3,5,9
  200.                                     ) b
  201.                                 ) c
  202.                                 GROUP BY 1,2,3,4,5,6,7
  203.                             ) d
  204.                             GROUP BY 1,2,3,4,5
  205.                         ) e
  206.                         GROUP BY 1,2
  207.                         ORDER BY 1",
  208.                         $periodos['from']['ano'] . $periodos['from']['periodo'],
  209.                         $periodos['to']['ano'] . $periodos['to']['periodo'],
  210.                         $periodos['from']['ano'] . $periodos['from']['periodo'],
  211.                         $periodos['to']['ano'] . $periodos['to']['periodo'],
  212.                         $programa['programa']['id_programa'],
  213.                         $programa['modelagem'],
  214.                         $busca[0] ?? '',
  215.                         $programa['where'],
  216.                         $busca[1] ?? '',
  217.                         $gestor_permissoes,
  218.                         $programa['modelagem'],
  219.                         $programa['programa']['id_programa']
  220.                     );
  221.                     $sql sprintf("SELECT
  222.                                         id_dominio,
  223.                                         nome_dominio,
  224.                                         Jsonb_Agg(e) indicadores
  225.                                     FROM (
  226.                                         SELECT
  227.                                             id_indicador,
  228.                                             id_dominio,
  229.                                             nome_indicador,
  230.                                             nome_dominio,
  231.                                             total_indicador,
  232.                                             Jsonb_Agg(contagem     ORDER BY performance ASC) contagem,
  233.                                             Jsonb_Agg(performance  ORDER BY performance ASC) performance,
  234.                                             Jsonb_Agg(porcentagem  ORDER BY performance ASC) porcentagem
  235.                                         FROM (
  236.                                             SELECT
  237.                                                 id_indicador,
  238.                                                 id_dominio,
  239.                                                 nome_indicador,
  240.                                                 nome_dominio,
  241.                                                 total_indicador,
  242.                                                 performance_decil as performance,
  243.                                                 COUNT(1)contagem,
  244.                                                 CASE
  245.                                                     WHEN total_indicador > 0 THEN ROUND( (COUNT(1)::numeric * 100) / total_indicador::numeric, 3)
  246.                                                     ELSE 0
  247.                                                 END porcentagem
  248.                                             FROM (
  249.                                                 SELECT
  250.                                                     b.*,
  251.                                                     COUNT(1) OVER(PARTITION BY id_indicador) total_indicador
  252.                                                 FROM (
  253.                                                     SELECT 
  254.                                                     a.*,
  255.                                                         CASE
  256.                                                         WHEN ROUND(performance, 2) = 100 THEN 100.00
  257.                                                         WHEN ROUND(performance, 2) BETWEEN 90 AND 99.99 THEN 90.00
  258.                                                         WHEN ROUND(performance, 2) BETWEEN 80 AND 89.99 THEN 80.00
  259.                                                         WHEN ROUND(performance, 2) BETWEEN 70 AND 79.99 THEN 70.00
  260.                                                         WHEN ROUND(performance, 2) BETWEEN 60 AND 69.99 THEN 60.00
  261.                                                         WHEN ROUND(performance, 2) BETWEEN 50 AND 59.99 THEN 50.00
  262.                                                         WHEN ROUND(performance, 2) BETWEEN 40 AND 49.99 THEN 40.00
  263.                                                         WHEN ROUND(performance, 2) BETWEEN 30 AND 39.99 THEN 30.00
  264.                                                         WHEN ROUND(performance, 2) BETWEEN 20 AND 29.99 THEN 20.00
  265.                                                         WHEN ROUND(performance, 2) BETWEEN 10 AND 19.99 THEN 10.00
  266.                                                         WHEN ROUND(performance, 2) BETWEEN 0 AND 9.99 THEN 0.00
  267.                                                         ELSE ROUND(performance, 2)
  268.                                                     END performance_decil
  269.                                                     FROM dados.calculo a 
  270.                                                     WHERE Concat(a.periodo->>'ano', a.periodo->>'periodo')::integer BETWEEN %s AND %s AND id_programa = %s AND id_modelagem = %s %s %s %s %s
  271.                                                 ) b
  272.                                             ) c
  273.                                             GROUP BY 1,2,3,4,5,6
  274.                                         ) d
  275.                                         GROUP BY 1,2,3,4,5
  276.                                     ) e
  277.                                     GROUP BY 1,2
  278.                                     ORDER BY 1",
  279.                                     $periodos['from']['ano'] . $periodos['from']['periodo'],
  280.                                     $periodos['to']['ano'] . $periodos['to']['periodo'],
  281.                                     $programa['programa']['id_programa'],
  282.                                     $programa['modelagem'],
  283.                                     $busca[0] ?? '',
  284.                                     $programa['where'],
  285.                                     $busca[1] ?? '',
  286.                                     $gestor_permissoes
  287.             );
  288.             
  289.         return $this->_em->getConnection()->executeQuery($sql);
  290.     }
  291.     /**
  292.      * @param string $ano
  293.      * @param integer $id_modelagem
  294.      * @param integer $id_grupo
  295.      * @param string $gestor_permissoes
  296.      * @return array
  297.      */
  298.     public function getInformacaoIndicadores(string $anoint $id_modelagemint $id_grupostring $gestor_permissoes ''): array
  299.     {
  300.         $fnWhereGrupo = function($alias) use($id_grupo) {
  301.             return ( $id_grupo ) ? "AND {$alias}.id_grupo = {$id_grupo}'';
  302.         };
  303.         $periodos "(periodo->>'ano') = :ano";
  304.         
  305.         if(!is_int($ano)) {
  306.             $explodeAno explode('-'$ano);
  307.             $periodos "CONCAT(periodo->>'ano', periodo->>'periodo')::int BETWEEN " $explodeAno[0] . " AND " $explodeAno[1];
  308.         }
  309.         $sql "
  310.             WITH _modelagem AS (
  311.                 SELECT DISTINCT
  312.                      ms.id_indicador
  313.                     ,mi.titulo nome_indicador
  314.                     ,mi.id_dominio
  315.                     ,md.titulo nome_dominio
  316.                     ,md.ordem
  317.                 FROM
  318.                     modelagem.scorecard ms
  319.                     JOIN modelagem.indicador mi USING(id_indicador)
  320.                     JOIN modelagem.dominio md USING(id_dominio)
  321.                 WHERE
  322.                     ms.id_modelagem = :id_modelagem
  323.                     AND ".$explodeAno[0]." >= ms.inicio AND ".$explodeAno[1]." <= ms.fim
  324.                     "$fnWhereGrupo('ms') ."
  325.                 ORDER BY
  326.                     md.ordem
  327.             ), _calculo AS (
  328.                 SELECT
  329.                      m.id_dominio
  330.                     ,m.nome_dominio
  331.                     ,m.id_indicador
  332.                     ,m.nome_indicador
  333.                     ,m.ordem
  334.                     ,dc.qtde_calculos
  335.                     ,dc.media_valor
  336.                     ,dc.media_performance
  337.                     ,dc.periodo
  338.                     ,dc.mes
  339.                     ,dc.mes_txt
  340.                 FROM _modelagem m LEFT JOIN (
  341.                     SELECT DISTINCT ON(id_indicador, periodo)
  342.                          dc.id_dominio
  343.                         ,dc.nome_dominio
  344.                         ,dc.id_indicador
  345.                         ,dc.nome_indicador
  346.                         ,Count(1) OVER w_ip qtde_calculos
  347.                         ,(Avg(dc.valor) OVER w_ip)::numeric(10,2) media_valor
  348.                         ,(Avg(dc.performance)  OVER w_ip)::numeric(10,2) media_performance
  349.                         ,((dc.periodo->>'ano')||(dc.periodo->>'periodo'))::integer periodo
  350.                         ,(dc.periodo->>'periodo')::integer mes
  351.                         ,(ARRAY['jan','fev','mar','abr','mai','jun','jul','ago','set','out','nov','dez'])[(dc.periodo->>'periodo')::integer] mes_txt
  352.                     FROM
  353.                         dados.calculo dc
  354.                     WHERE
  355.                         CONCAT(dc.periodo->>'ano', dc.periodo->>'periodo')::int BETWEEN %s AND %s
  356.                         AND dc.periodo->>'tipo' = 'mes'
  357.                         AND dc.id_modelagem = :id_modelagem
  358.                         "$fnWhereGrupo('dc') ."
  359.                     WINDOW
  360.                         w_ip AS(PARTITION BY id_indicador, periodo)
  361.                 ) dc USING(id_indicador, id_dominio)
  362.             ), _resultado AS (
  363.                 SELECT
  364.                      c.*
  365.                     ,a.qtde_avaliados
  366.                     ,CASE WHEN a.qtde_avaliados::numeric > 0 THEN ((c.qtde_calculos::numeric / a.qtde_avaliados::numeric) * 100)::numeric(10,2) ELSE 0 END perc_calc
  367.                 FROM
  368.                     _calculo c
  369.                     JOIN LATERAL (
  370.                         SELECT
  371.                             Count(1) qtde_avaliados
  372.                         FROM
  373.                             modelagem.avaliacao ma
  374.                             JOIN modelagem.scorecard ms ON(
  375.                                 ms.id_grupo = ma.id_grupo
  376.                                 AND ms.id_indicador = c.id_indicador
  377.                                 AND ms.id_modelagem = :id_modelagem
  378.                                 "$fnWhereGrupo('ms') ."
  379.                             )
  380.                         WHERE
  381.                             ma.id_modelagem = :id_modelagem
  382.                             AND (c.periodo BETWEEN ma.inicio AND ma.fim)
  383.                             AND (c.periodo BETWEEN ms.inicio AND ms.fim)
  384.                     ) a ON TRUE
  385.                 ORDER BY
  386.                      c.nome_dominio
  387.                     ,c.nome_indicador
  388.             )
  389.             SELECT
  390.                  id_dominio
  391.                 ,nome_dominio
  392.                 ,id_indicador
  393.                 ,nome_indicador
  394.                 ,AVG(media_performance) media_media_performance
  395.                 ,jsonb_agg(qtde_calculos ORDER BY periodo) qtde_calculos
  396.                 ,jsonb_agg(media_valor ORDER BY periodo) media_valor
  397.                 ,jsonb_agg(media_performance ORDER BY periodo) media_performance
  398.                 ,jsonb_agg(qtde_avaliados ORDER BY periodo) qtde_avaliados
  399.                 ,jsonb_agg(perc_calc ORDER BY periodo) perc_calc
  400.                 ,jsonb_agg(mes_txt ORDER BY periodo) mes_txt
  401.                 ,jsonb_agg(mes ORDER BY periodo) mes
  402.                 ,jsonb_agg(periodo ORDER BY periodo) periodo
  403.             FROM
  404.                 _resultado
  405.             WHERE TRUE {$gestor_permissoes}
  406.             GROUP BY
  407.                  id_dominio
  408.                 ,nome_dominio
  409.                 ,id_indicador
  410.                 ,nome_indicador
  411.         ";
  412.         
  413.         $sql sprintf($sqlexplode('-'$ano)[0], explode('-'$ano)[1]);
  414.         $stmt $this->_em->getConnection()->prepare($sql);
  415.         $stmt->bindValue(':id_modelagem'$id_modelagemParameterType::INTEGER);
  416.         return $stmt->executeQuery()->fetchAllAssociative();
  417.     }
  418.     public function str_replace_first($search$replace$subject)
  419.     {
  420.         $search '/'.preg_quote($search'/').'/';
  421.         return preg_replace($search$replace$subject1);
  422.     }
  423.     /**
  424.      * Undocumented function
  425.      *
  426.      * @param integer $ano
  427.      * @param Modelagem $modelagem
  428.      * @param integer $id_grupo
  429.      * @param string $gestor_permissoes
  430.      * @return ResultStatement|null
  431.      */
  432.     public function getInformacaoAvaliadosEvsProdcao($anoModelagem $modelagemint $id_grupostring $gestor_permissoes ''bool $evs true): ?ResultStatement
  433.     {
  434.         $tabela 'evs';
  435.         $campo 'valor';
  436.         $toChar '0D99';
  437.         if (!$evs) {
  438.             $tabela 'gps';
  439.             $campo 'performance';
  440.             $toChar '999D99%';
  441.         }
  442.         $andIdGrupo NULL;
  443.         if ( $id_grupo ) {
  444.             $andIdGrupo 'AND id_grupo = :id_grupo';
  445.         }
  446.         $periodos "(periodo->>'ano') = :ano";
  447.         
  448.         if(!is_int($ano)) {
  449.             $explodeAno explode('-'$ano);
  450.             $periodos "CONCAT(periodo->>'ano', periodo->>'periodo')::int BETWEEN " $explodeAno[0] . " AND " $explodeAno[1];
  451.         }
  452.         
  453.         // prepare sql
  454.         $sql "
  455.             WITH _{$tabela} AS (
  456.                 SELECT
  457.                     id_avaliado
  458.                     ,nome_avaliado
  459.                     ,id_grupo
  460.                     ,nome_grupo
  461.                     ,Concat(periodo->>'ano', periodo->>'periodo')::int periodo
  462.                     ,{$campo} {$tabela}
  463.                     ,Trim(To_Char({$campo}, '{$toChar}')) {$tabela}_txt
  464.                     ,Round(Avg({$campo}) OVER(PARTITION BY id_grupo, id_avaliado), 2) AS {$tabela}_anual
  465.                     ,Trim(To_Char(Round(Avg({$campo}) OVER(PARTITION BY id_grupo, id_avaliado), 2), '{$toChar}')) AS {$tabela}_anual_txt
  466.                 FROM
  467.                     dados.{$tabela}
  468.                 WHERE
  469.                     {$periodos}                  
  470.                     AND id_modelagem = :id_modelagem
  471.                     {$gestor_permissoes}
  472.                     {$andIdGrupo}
  473.             )
  474.             SELECT DISTINCT
  475.                  {$tabela}.*
  476.                 ,Substring({$tabela}.periodo::text,5,2)::integer periodo_mes
  477.                 ,To_Char((({$tabela}.periodo)::text||'01')::date,'MM')::int periodo_txt
  478.             FROM
  479.                 _{$tabela} {$tabela}
  480.             ORDER BY
  481.                     {$tabela}.{$tabela}_anual DESC
  482.                 ,{$tabela}.periodo
  483.                 ,{$tabela}.id_avaliado
  484.         ";
  485.             
  486.         $stmt $this->_em->getConnection()->prepare($sql);
  487.         if(is_int($ano)) {
  488.             $stmt->bindValue(':ano'$anoParameterType::INTEGER);
  489.         }
  490.         $stmt->bindValue(':id_modelagem'$modelagem->getIdModelagem(), ParameterType::INTEGER);
  491.         if ( $id_grupo ) {
  492.             $stmt->bindValue(':id_grupo'$id_grupoParameterType::INTEGER);
  493.         }
  494.         
  495.         return $stmt->executeQuery();
  496.     }
  497.     
  498.     /**
  499.      * @param integer $ano
  500.      * @param Modelagem $modelagem
  501.      * @param integer $id_grupo
  502.      * @param string $gestor_permissoes
  503.      * @return Result|null
  504.      */
  505.     public function getInformacaoEspecialidadesEvsProducao($anoModelagem $modelagemint $id_grupostring $gestor_permissoes ''bool $evs true): ?Result
  506.     {
  507.         $tabela 'evs';
  508.         $campo 'valor';
  509.         $toChar '0D99';
  510.         if (!$evs) {
  511.             $tabela 'gps';
  512.             $campo 'performance';
  513.             $toChar '999D99%';
  514.         }
  515.         $andIdGrupo NULL;
  516.         if ( $id_grupo ) {
  517.             $andIdGrupo 'AND id_grupo = :id_grupo';
  518.         }
  519.         $periodos "(periodo->>'ano') = :ano";
  520.         if(!is_int($ano)) {
  521.             $explodeAno explode('-'$ano);
  522.             $periodos "CONCAT(periodo->>'ano', periodo->>'periodo')::int BETWEEN " $explodeAno[0] . " AND " $explodeAno[1];
  523.         }
  524.         // prepare sql
  525.         $sql "WITH _{$tabela} AS (
  526.                     SELECT id_grupo
  527.                         ,nome_grupo
  528.                         ,Concat(periodo->>'ano', periodo->>'periodo')::int periodo
  529.                         ,{$campo} {$tabela}
  530.                         ,Round(Avg({$campo}) OVER(PARTITION BY id_grupo), 2) AS {$tabela}_anual
  531.                         ,Trim(To_Char(Round(Avg({$campo}) OVER(PARTITION BY id_grupo), 2), '{$toChar}')) AS {$tabela}_anual_txt
  532.                     FROM
  533.                         dados.{$tabela}
  534.                     WHERE
  535.                         {$periodos}
  536.                         AND id_modelagem = :id_modelagem
  537.                         {$gestor_permissoes}
  538.                         {$andIdGrupo}
  539.                 )
  540.                 SELECT
  541.                       {$tabela}.id_grupo
  542.                     , MAX({$tabela}.nome_grupo) AS nome_grupo
  543.                     , ROUND(AVG({$tabela}.{$tabela}), 2) AS {$tabela}
  544.                     , TRIM(To_Char(ROUND(AVG({$tabela}.{$tabela}), 2), '{$toChar}')) AS {$tabela}_media_txt
  545.                     , ROUND(AVG({$tabela}.{$tabela}_anual), 2) AS {$tabela}_anual
  546.                     , TRIM(TO_CHAR(ROUND(AVG({$tabela}.{$tabela}), 2), '{$toChar}')) AS {$tabela}_txt
  547.                     , MAX({$tabela}_anual_txt) AS {$tabela}_anual_txt
  548.                     , {$tabela}.periodo
  549.                     , Substring({$tabela}.periodo::text, 5, 2)::integer periodo_mes
  550.                     , To_Char((({$tabela}.periodo)::text || '01')::date, 'MM')::int periodo_txt
  551.                 FROM
  552.                     _{$tabela} {$tabela}
  553.                 GROUP BY
  554.                     {$tabela}.id_grupo, periodo
  555.                 ORDER BY
  556.                     {$tabela} DESC,
  557.                     {$tabela}.id_grupo,
  558.                     {$tabela}.periodo
  559.         ";
  560.         $stmt $this->_em->getConnection()->prepare($sql);
  561.         if(is_int($ano)) {
  562.             $stmt->bindValue(':ano'$anoParameterType::INTEGER);
  563.         }
  564.         $stmt->bindValue(':id_modelagem'$modelagem->getIdModelagem(), ParameterType::INTEGER);
  565.         if ( $id_grupo ) {
  566.             $stmt->bindValue(':id_grupo'$id_grupoParameterType::INTEGER);
  567.         }
  568.         return $stmt->executeQuery();
  569.     }
  570.     /**
  571.      * Undocumented function
  572.      *
  573.      * @param integer $ano
  574.      * @param Modelagem $modelagem
  575.      * @param integer $id_grupo
  576.      * @param string $gestor_permissoes
  577.      * @return ResultStatement|null
  578.      */
  579.     public function getInformacaoAvaliadosEvsProducaoRede($anoModelagem $modelagemint $id_grupostring $gestor_permissoes ''bool $evs true): ?ResultStatement
  580.     {
  581.         $tabela 'evs';
  582.         $campo 'valor';
  583.         $toChar '0D99';
  584.         if (!$evs) {
  585.             $tabela 'gps';
  586.             $campo 'performance';
  587.             $toChar '999D99%';
  588.         }
  589.         $modelagemConfig $modelagem->getConfig() ?? [];
  590.         // sem regra configurada para producao
  591.         if ( !array_key_exists('producao'$modelagemConfig) ) {
  592.             return NULL;
  593.         }
  594.         // array de producao
  595.         $jsonProducao $modelagemConfig['producao'];
  596.         $queryOrTabelaProducao array_filter($jsonProducao, function($value$key) {
  597.             return (in_array($key, ['query','tabela']) AND strlen($value) > 5);
  598.         },ARRAY_FILTER_USE_BOTH);
  599.         // sem campos configurados
  600.         if ( count($queryOrTabelaProducao) === ) {
  601.             return NULL;
  602.         }
  603.         if ( array_key_exists('tabela'$queryOrTabelaProducao) ) {
  604.             $columnIdAvaliado = ('layout_drg_2im_out' === $queryOrTabelaProducao['tabela']) ? 'cod_crm id_avaliado' 'id_avaliado';
  605.             $queryOrTabelaProducao "SELECT DISTINCT {$columnIdAvaliado} FROM robot.{$queryOrTabelaProducao['tabela']} WHERE periodo = :periodo";
  606.         } else {
  607.             $queryOrTabelaProducao $queryOrTabelaProducao['query'];
  608.             if(strstr($queryOrTabelaProducao'layout_drg_2im_out')) {
  609.                 $queryOrTabelaProducao $this->str_replace_first('cod_crm','cod_crm id_avaliado',$queryOrTabelaProducao);
  610.             }
  611.         }
  612.         // replece bind
  613.         $queryOrTabelaProducao str_replace(['{%PERIODO%}',':periodo'],"{$tabela}.periodo"$queryOrTabelaProducao);
  614.         $andIdGrupo NULL;
  615.         if ( $id_grupo ) {
  616.             $andIdGrupo 'AND id_grupo = :id_grupo';
  617.         }
  618.         $periodos "(periodo->>'ano') = :ano";
  619.         
  620.         if(!is_int($ano)) {
  621.             $explodeAno explode('-'$ano);
  622.             $periodos "CONCAT(periodo->>'ano', periodo->>'periodo')::int BETWEEN " $explodeAno[0] . " AND " $explodeAno[1];
  623.         }
  624.         
  625.         // prepare sql
  626.         $sql "
  627.             WITH _{$tabela} AS (
  628.                 SELECT
  629.                     id_avaliado
  630.                     ,nome_avaliado
  631.                     ,id_grupo
  632.                     ,nome_grupo
  633.                     ,id_modelagem
  634.                     , nome_modelagem
  635.                     ,Concat(periodo->>'ano', periodo->>'periodo')::int periodo
  636.                     ,{$campo} {$tabela}
  637.                     ,Trim(To_Char({$campo}, '{$toChar}')) {$tabela}_txt
  638.                     ,Round(Avg({$campo}) OVER(PARTITION BY id_modelagem, id_grupo, id_avaliado), 2) AS {$tabela}_anual
  639.                     ,Trim(To_Char(Round(Avg({$campo}) OVER(PARTITION BY id_modelagem, id_grupo, id_avaliado), 2), '{$toChar}')) AS {$tabela}_anual_txt
  640.                 FROM
  641.                     dados.{$tabela}
  642.                 WHERE
  643.                     {$periodos}               
  644.                     {$gestor_permissoes}
  645.                     {$andIdGrupo}
  646.             )
  647.             SELECT DISTINCT
  648.                  {$tabela}.*
  649.                 ,prod.id_avaliado IS NOT NULL is_producao
  650.                 ,Substring({$tabela}.periodo::text,5,2)::integer periodo_mes
  651.                 ,To_Char((({$tabela}.periodo)::text||'01')::date,'MM')::int periodo_txt
  652.             FROM
  653.                 _{$tabela} {$tabela}
  654.                 LEFT JOIN LATERAL (
  655.                     {$queryOrTabelaProducao}
  656.                 ) prod USING(id_avaliado)
  657.             ORDER BY
  658.                     {$tabela}.{$tabela}_anual DESC
  659.                 ,{$tabela}.periodo
  660.                 ,{$tabela}.id_avaliado
  661.         ";
  662.                     
  663.         $stmt $this->_em->getConnection()->prepare($sql);
  664.         if(is_int($ano)) {
  665.             $stmt->bindValue(':ano'$anoParameterType::INTEGER);
  666.         }
  667.         if ( $id_grupo ) {
  668.             $stmt->bindValue(':id_grupo'$id_grupoParameterType::INTEGER);
  669.         }
  670.         if (strstr($queryOrTabelaProducao':id_modelagem_rule') != false) {
  671.             $stmt->bindValue(':id_modelagem_rule'$modelagem->getIdModelagem(), ParameterType::INTEGER);
  672.         }
  673.         
  674.         return $stmt->executeQuery();
  675.     }
  676.     /**
  677.      * @param array $programa
  678.      * @param array $periodos
  679.      * @param integer $id_indicador
  680.      * @param float $performance
  681.      * @param array $filtro
  682.      * @return array
  683.      */
  684.     public function getDetalhesDistribuicaoDesempenho(array $programa, array $periodosint $id_indicadorfloat $performance, array $filtro) :array
  685.     {
  686.         if ( count($filtro) > ) {
  687.             $filtro $filtro[0];
  688.             $campoBandas ',dados bandas';
  689.         } else {
  690.             $filtro '';
  691.             $campoBandas '';
  692.         }
  693.         $sql "
  694.             SELECT
  695.                 *
  696.                 ,Sum(qtde_ocorrencia) OVER(ORDER BY qtde_ocorrencia DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) rank
  697.                 ,Sum(qtde_ocorrencia) OVER() total
  698.             FROM (
  699.                 SELECT DISTINCT ON(id_avaliado)
  700.                     id_avaliado
  701.                     ,nome_avaliado
  702.                     ,id_indicador
  703.                     ,nome_indicador
  704.                     ,First_Value(nome_grupo) OVER(PARTITION BY id_avaliado) nome_grupo
  705.                     ,ROUND(performance, 2) performance
  706.                     ,COUNT(1) OVER(PARTITION BY id_avaliado) qtde_ocorrencia
  707.                     {$campoBandas}
  708.                     ,Array_To_String(Array_Agg(Concat(periodo->>'periodo','/',periodo->>'ano')) OVER(PARTITION BY id_avaliado),',') referencias
  709.                 FROM
  710.                     dados.calculo
  711.                 WHERE TRUE
  712.                     {$periodos['where']}
  713.                     {$programa['where']}
  714.                     AND id_indicador = :id_indicador
  715.                     AND ROUND(performance, 2) = :performance
  716.                     {$filtro}
  717.             ) a
  718.             ORDER BY
  719.                 qtde_ocorrencia DESC
  720.         ";
  721.         
  722.         $stmt $this->_em->getConnection()->prepare($sql);
  723.         $stmt->bindValue(':id_indicador'$id_indicadorParameterType::INTEGER);
  724.         $stmt->bindValue(':performance'$performanceParameterType::INTEGER);
  725.         return $stmt->executeQuery()->fetchAllAssociative();
  726.     }
  727.     /**
  728.      * @return array
  729.      */
  730.     public function getDetalhesDesempenhoIndicador(int $id_indicador, array $periodos, array $filtros, array $programaint $faixa)
  731.     {
  732.         $whereFiltro '';
  733.         if (count($filtros) > 0) {
  734.             foreach ($filtros as $filtro) {
  735.                 $whereFiltro .= $filtro ' ';
  736.             }
  737.         }
  738.         $whereFaixa '';
  739.         $wherePerformance '';
  740.         if ( $faixa >= && $faixa <= 100 ) {
  741.             $whereFaixa =  "AND performance BETWEEN {$faixa} AND {$faixa}+9.99";
  742.         } else if ($faixa == -1) {
  743.             $wherePerformance "WHERE performance_0 > 0";
  744.         }
  745.         $sql "SELECT * FROM (
  746.                     SELECT
  747.                         id_avaliado
  748.                         , nome_avaliado
  749.                         , id_indicador
  750.                         ,Concat(id_indicador, ' - ', nome_indicador) indicador
  751.                         ,unidade_indicador
  752.                         ,nome_grupo
  753.                         ,avaliado_media_performance
  754.                         , COUNT(1) FILTER(WHERE performance IS NULL) performance_0
  755.                         , COUNT(1) FILTER(WHERE performance IS NOT NULL) performance_1
  756.                         , jsonb_object_agg(periodo, performance) performances
  757.                         , jsonb_object_agg(periodo, valor) valores_absolutos
  758.                         , jsonb_object_agg(periodo, numerador) numerador
  759.                         , jsonb_object_agg(periodo, denominador) denominador
  760.                     FROM (
  761.                         SELECT
  762.                             a.*
  763.                             , periodo
  764.                             , ROUND(b.performance, 2) performance
  765.                             , ROUND(b.valor, 2) valor
  766.                             ,ROUND(Avg(performance) OVER(PARTITION BY a.id_avaliado), 2) avaliado_media_performance
  767.                             , ROUND(b.numerador, 2) numerador
  768.                             , ROUND(b.denominador, 2) denominador
  769.                         FROM generate_periodo(%s, %s) AS periodo
  770.                         JOIN LATERAL (
  771.                             SELECT distinct id_avaliado, nome_avaliado, id_indicador, nome_indicador, First_Value(nome_grupo) OVER(PARTITION BY id_avaliado) nome_grupo, unidade_indicador
  772.                             FROM dados.calculo 
  773.                             WHERE TRUE
  774.                                 {$programa['where']}
  775.                                 {$periodos['where']}
  776.                                 AND id_indicador = {$id_indicador}
  777.                                 {$whereFaixa}
  778.                                 {$whereFiltro}
  779.                         ) a ON TRUE
  780.                         LEFT JOIN (
  781.                             SELECT
  782.                                 id_avaliado
  783.                                 , nome_avaliado
  784.                                 , CONCAT(periodo->>'ano',periodo->>'periodo')::int AS periodo
  785.                                 , performance
  786.                                 , valor
  787.                                 , numerador
  788.                                 , denominador
  789.                             FROM dados.calculo
  790.                             WHERE TRUE
  791.                                 {$programa['where']}
  792.                                 {$periodos['where']}
  793.                                 AND id_indicador = {$id_indicador}
  794.                         ) b USING(id_avaliado, nome_avaliado, periodo)
  795.                     ) c
  796.                     GROUP BY 1,2,id_indicador,nome_indicador, 4,5,6,7
  797.                     ORDER BY 5 DESC, 1
  798.                     ) d
  799.                     {$wherePerformance}";
  800.         $sql sprintf($sql
  801.                 $periodos['from']['ano'] . $periodos['from']['periodo'],
  802.                 $periodos['to']['ano'] . $periodos['to']['periodo']);
  803.                             
  804.         $stmt $this->_em->getConnection()->prepare($sql);
  805.         return $stmt->executeQuery()->fetchAllAssociative();
  806.     }
  807.     /**
  808.      * @return array
  809.      */
  810.     public function getDetalhesDesempenhoIndicadorNovoCalculoFaixa(int $id_indicador, array $periodos, array $filtros, array $programaint $faixa)
  811.     {
  812.         //adicionando alias nessas colunas para otimização da query
  813.         $periodos['where'] = str_replace('periodo->>''dc.periodo->>'$periodos['where']);
  814.         $programa['where'] = str_replace('id_programa''dc.id_programa'$programa['where']);
  815.         $programa['where'] = str_replace('id_modelagem''dc.id_modelagem'$programa['where']);
  816.         $whereFiltro '';
  817.         if (count($filtros) > 0) {
  818.             foreach ($filtros as $filtro) {
  819.                 $whereFiltro .= $filtro ' ';
  820.             }
  821.         }
  822.         $whereFaixa '';
  823.         $wherePerformance '';
  824.         if ( $faixa >= && $faixa <= 100 ) {
  825.             $whereFaixa =  "AND performance BETWEEN {$faixa} AND {$faixa}+9.99";
  826.         } else if ($faixa == -1) {
  827.             $wherePerformance "WHERE performance_0 > 0";
  828.         }
  829.         $sql "SELECT * FROM (
  830.                     SELECT
  831.                         id_avaliado
  832.                         , nome_avaliado
  833.                         , id_indicador
  834.                         , Concat(id_indicador, ' - ', nome_indicador) indicador
  835.                         , unidade_indicador
  836.                         , nome_grupo
  837.                         , risco
  838.                         , avaliado_media_performance
  839.                         , jsonb_object_agg(periodo, jsonb_build_object(
  840.                                 'risco', risco,
  841.                                 'performance_risco', performance_risco,
  842.                                 'performance', performance,
  843.                                 'numerador', numerador,
  844.                                 'denominador', denominador,
  845.                                 'valor', valor
  846.                             )
  847.                         ) AS resultado
  848.                         , COUNT(1) FILTER(WHERE performance IS NULL) performance_0
  849.                         , COUNT(1) FILTER(WHERE performance IS NOT NULL) performance_1
  850.                         , jsonb_object_agg(periodo, performance) performances
  851.                     FROM (
  852.                         SELECT
  853.                             b.cod_ajuste AS risco
  854.                             , a.*
  855.                             , periodo
  856.                             , ROUND(b.performance, 2) performance
  857.                             , ROUND(b.valor, 2) valor
  858.                             , ROUND(AVG(performance) OVER(PARTITION BY a.id_avaliado), 2) avaliado_media_performance
  859.                             , performance_risco
  860.                             , ROUND(b.numerador, 2) numerador
  861.                             , ROUND(b.denominador, 2) denominador
  862.                         FROM generate_periodo(%s, %s) AS periodo
  863.                         JOIN LATERAL (
  864.                             SELECT
  865.                                 DISTINCT dc.id_avaliado,
  866.                                 dc.nome_avaliado,
  867.                                 dc.id_indicador,
  868.                                 dc.nome_indicador,
  869.                                 FIRST_VALUE(dc.nome_grupo) OVER(PARTITION BY dc.id_avaliado) nome_grupo,
  870.                                 dc.unidade_indicador
  871.                             FROM dados.novo_calculo dn
  872.                             LEFT JOIN dados.calculo dc USING(id_avaliado, id_indicador, id_modelagem, id_programa, periodo)
  873.                             WHERE TRUE
  874.                                 {$programa['where']}
  875.                                 {$periodos['where']}
  876.                                 AND dc.id_indicador = {$id_indicador}
  877.                                 {$whereFaixa}
  878.                                 ".str_replace('id_grupo''dn.id_grupo',$whereFiltro)."
  879.                 
  880.                         ) a ON TRUE
  881.                         LEFT JOIN (
  882.                             SELECT
  883.                                 (dn.detalhes->'data'->0->>'cod_ajuste')::numeric AS cod_ajuste
  884.                                 , dc.id_avaliado
  885.                                 , dc.nome_avaliado
  886.                                 , CONCAT(dc.periodo->>'ano', dc.periodo->>'periodo')::int AS periodo
  887.                                 , dc.performance
  888.                                 , dc.valor
  889.                                 , (dn.detalhes->'data'->0->>'resultado')::numeric AS performance_risco
  890.                                 , (dn.detalhes->'data'->0->>'numerador')::numeric AS numerador
  891.                                 , (dn.detalhes->'data'->0->>'denominador')::numeric AS denominador
  892.                             FROM dados.novo_calculo dn
  893.                             LEFT JOIN dados.calculo dc USING(id_avaliado, id_indicador, id_modelagem, id_programa, periodo)
  894.                             WHERE TRUE
  895.                                 {$programa['where']}
  896.                                 {$periodos['where']}
  897.                                 AND dc.id_indicador = {$id_indicador}
  898.                             ORDER BY 2,4,1
  899.                         ) b USING(id_avaliado, nome_avaliado, periodo)
  900.                     ) e
  901.                 
  902.                     GROUP BY 1,2,id_indicador,nome_indicador,4,5,6,risco,7,8
  903.                     ORDER BY 5 DESC, 1
  904.                 ) d
  905.                 {$wherePerformance}";
  906.         $sql sprintf($sql
  907.                 $periodos['from']['ano'] . $periodos['from']['periodo'],
  908.                 $periodos['to']['ano'] . $periodos['to']['periodo']);      
  909.                 
  910.         $stmt $this->_em->getConnection()->prepare($sql);
  911.         return $stmt->executeQuery()->fetchAllAssociative();
  912.     }
  913.     public function getDetalhesDesempenhoIndicadorDistribuicao(int $id_indicadorstring $periodo, array $filtros, array $programa)
  914.     {
  915.         $whereFiltro '';
  916.         if (count($filtros) > 0) {
  917.             foreach ($filtros as $filtro) {
  918.                 $whereFiltro .= $filtro ' ';
  919.             }
  920.         }
  921.         $sql "SELECT * FROM (
  922.                     SELECT
  923.                         id_avaliado
  924.                         , nome_avaliado
  925.                         , id_indicador
  926.                         ,Concat(id_indicador, ' - ', nome_indicador) indicador
  927.                         ,unidade_indicador
  928.                         ,nome_grupo
  929.                         ,avaliado_media_performance
  930.                         , COUNT(1) FILTER(WHERE performance IS NULL) performance_0
  931.                         , COUNT(1) FILTER(WHERE performance IS NOT NULL) performance_1
  932.                         , jsonb_object_agg(periodo, performance) performances
  933.                         , jsonb_object_agg(periodo, valor) valores_absolutos
  934.                         , jsonb_object_agg(periodo, numerador) numerador
  935.                         , jsonb_object_agg(periodo, denominador) denominador
  936.                     FROM (
  937.                         SELECT
  938.                             a.*
  939.                             , periodo
  940.                             , ROUND(b.performance, 2) performance
  941.                             , ROUND(b.valor, 2) valor
  942.                             ,ROUND(Avg(performance) OVER(PARTITION BY a.id_avaliado), 2) avaliado_media_performance
  943.                             , ROUND(b.numerador, 2) numerador
  944.                             , ROUND(b.denominador, 2) denominador
  945.                         FROM generate_periodo(%s, %s) AS periodo
  946.                         JOIN LATERAL (
  947.                             SELECT distinct id_avaliado, nome_avaliado, id_indicador, nome_indicador, First_Value(nome_grupo) OVER(PARTITION BY id_avaliado) nome_grupo, unidade_indicador
  948.                             FROM dados.calculo 
  949.                             WHERE TRUE
  950.                                 {$programa['where']}
  951.                                 AND CONCAT(periodo->>'ano', LPAD(periodo->>'periodo', 2, '0'))::int = {$periodo}
  952.                                 AND id_indicador = {$id_indicador}
  953.                                 {$whereFiltro}
  954.                         ) a ON TRUE
  955.                         LEFT JOIN (
  956.                             SELECT
  957.                                 id_avaliado
  958.                                 , nome_avaliado
  959.                                 , CONCAT(periodo->>'ano',periodo->>'periodo')::int AS periodo
  960.                                 , performance
  961.                                 , valor
  962.                                 , numerador
  963.                                 , denominador
  964.                             FROM dados.calculo
  965.                             WHERE TRUE
  966.                                 {$programa['where']}
  967.                                 AND CONCAT(periodo->>'ano', LPAD(periodo->>'periodo', 2, '0'))::int = {$periodo}
  968.                                 AND id_indicador = {$id_indicador}
  969.                         ) b USING(id_avaliado, nome_avaliado, periodo)
  970.                     ) c
  971.                     GROUP BY 1,2,id_indicador,nome_indicador, 4,5,6,7
  972.                     ORDER BY 5 DESC, 1
  973.                     ) d";
  974.         $sql sprintf($sql$periodo$periodo);
  975.         $stmt $this->_em->getConnection()->prepare($sql);
  976.         return $stmt->executeQuery()->fetchAllAssociative();
  977.     }
  978.     public function getDetalhesDesempenhoIndicadorNovoCalculo(int $id_indicadorstring $periodo, array $filtros, array $programa)
  979.     {
  980.         $whereFiltro '';
  981.         if (count($filtros) > 0) {
  982.             foreach ($filtros as $filtro) {
  983.                 $whereFiltro .= $filtro ' ';
  984.             }
  985.         }
  986.         $sql "SELECT * FROM (
  987.                     SELECT
  988.                         id_avaliado
  989.                         , nome_avaliado
  990.                         , id_indicador
  991.                         , Concat(id_indicador, ' - ', nome_indicador) indicador
  992.                         , unidade_indicador
  993.                         , nome_grupo
  994.                         , risco
  995.                         , avaliado_media_performance
  996.                         , performance_risco
  997.                         , COUNT(1) FILTER(WHERE performance IS NULL) performance_0
  998.                         , COUNT(1) FILTER(WHERE performance IS NOT NULL) performance_1
  999.                         , jsonb_object_agg(periodo, performance) performances
  1000.                         , jsonb_object_agg(periodo, valor) valores_absolutos
  1001.                         , jsonb_object_agg(periodo, numerador) numerador
  1002.                         , jsonb_object_agg(periodo, denominador) denominador
  1003.                     FROM (
  1004.                         SELECT
  1005.                             b.cod_ajuste AS risco
  1006.                             , a.*
  1007.                             , periodo
  1008.                             , ROUND(b.performance, 2) performance
  1009.                             , ROUND(b.valor, 2) valor
  1010.                             , ROUND(AVG(performance) OVER(PARTITION BY a.id_avaliado), 2) avaliado_media_performance
  1011.                             , performance_risco
  1012.                             , ROUND(b.numerador, 2) numerador
  1013.                             , ROUND(b.denominador, 2) denominador
  1014.                         FROM generate_periodo(%s, %s) AS periodo
  1015.                         JOIN LATERAL (
  1016.                             SELECT
  1017.                                 DISTINCT dc.id_avaliado,
  1018.                                 dc.nome_avaliado,
  1019.                                 dc.id_indicador,
  1020.                                 dc.nome_indicador,
  1021.                                 FIRST_VALUE(dc.nome_grupo) OVER(PARTITION BY dc.id_avaliado) nome_grupo,
  1022.                                 dc.unidade_indicador
  1023.                             FROM dados.novo_calculo dn
  1024.                             JOIN dados.calculo dc USING(id_avaliado, id_indicador, id_modelagem, id_programa, periodo, id_grupo)
  1025.                             WHERE TRUE
  1026.                                 {$programa['where']}
  1027.                                 AND CONCAT(periodo->>'ano', LPAD(periodo->>'periodo', 2, '0'))::int = {$periodo}
  1028.                                 AND id_indicador = {$id_indicador}
  1029.                                 {$whereFiltro}
  1030.                         ) a ON TRUE
  1031.                         LEFT JOIN (
  1032.                             SELECT
  1033.                                 (dn.detalhes->'data'->0->>'cod_ajuste')::numeric AS cod_ajuste
  1034.                                 , dc.id_avaliado
  1035.                                 , dc.nome_avaliado
  1036.                                 , CONCAT(dc.periodo->>'ano', dc.periodo->>'periodo')::int AS periodo
  1037.                                 , dc.performance
  1038.                                 , dc.valor
  1039.                                 , (dn.detalhes->'data'->0->>'resultado')::numeric AS performance_risco
  1040.                                 , (dn.detalhes->'data'->0->>'numerador')::numeric AS numerador
  1041.                                 , (dn.detalhes->'data'->0->>'denominador')::numeric AS denominador
  1042.                             FROM dados.novo_calculo dn
  1043.                             JOIN dados.calculo dc USING(id_avaliado, id_indicador, id_modelagem, id_programa, periodo, id_grupo)
  1044.                             WHERE TRUE
  1045.                                 {$programa['where']}
  1046.                                 AND CONCAT(periodo->>'ano', LPAD(periodo->>'periodo', 2, '0'))::int = {$periodo}
  1047.                                 AND id_indicador = {$id_indicador}
  1048.                             ORDER BY 2,1
  1049.                         ) b USING(id_avaliado, nome_avaliado, periodo)
  1050.                     ) c
  1051.                     GROUP BY 1,2,id_indicador,nome_indicador,4,5,6,risco,7,8,9
  1052.                 ORDER BY 5 DESC, 1
  1053.                 ) d";
  1054.         $sql sprintf($sql$periodo$periodo);
  1055.         $stmt $this->_em->getConnection()->prepare($sql);
  1056.         return $stmt->executeQuery()->fetchAllAssociative();
  1057.     }
  1058.     public function checkIfHasBancoNovoCalculo($id_indicador)
  1059.     {
  1060.         $sql "SELECT EXISTS(
  1061.                     SELECT
  1062.                         FROM information_schema.tables
  1063.                     WHERE table_schema = 'dados' AND table_name = 'novo_calculo'
  1064.                 )
  1065.         ";
  1066.         if($this->_em->getConnection()->executeQuery($sql)->fetchOne()) {
  1067.             if($this->_em->getConnection()->executeQuery(
  1068.                 "SELECT count(1) FROM dados.novo_calculo WHERE id_indicador = {$id_indicador}"
  1069.             )->fetchOne() > 0){
  1070.                 return true;
  1071.             }
  1072.         }
  1073.         return false;
  1074.     }
  1075.     /**
  1076.      * Faz um count distinto da quantidade de Avaliados, Indicadores, Grupos e, caso o $programa venha sem 'id_modelagem', Modelagens
  1077.      *  da tabela dados.calculo para ser utilizado nos alertas da visão Gestor e Gestor de Rede
  1078.      */
  1079.     public function findQtdsAlertasGestor(array $periodos, array $filtros, array $programa, ?string $gestor_permissoes null)
  1080.     {
  1081.         $whereFiltro '';
  1082.         if (count($filtros) > 0) {
  1083.             foreach ($filtros as $filtro) {
  1084.                 $whereFiltro .= $filtro ' ';
  1085.             }
  1086.         }
  1087.         $countModelagens '';
  1088.         if (strstr($programa['where'], 'id_modelagem') == false) {
  1089.             $countModelagens 'COUNT(DISTINCT id_modelagem) qtd_modelagens,';
  1090.         }
  1091.         $sql "SELECT
  1092.                     {$countModelagens}
  1093.                     COUNT(DISTINCT id_avaliado) qtd_avaliados,
  1094.                     COUNT(DISTINCT id_indicador) qtd_indicadores,
  1095.                     COUNT(DISTINCT id_grupo) qtd_grupos
  1096.                 FROM
  1097.                     dados.calculo c
  1098.                 WHERE CONCAT(periodo->>'ano',periodo->>'periodo')::int BETWEEN ".$periodos['from']['ano'].$periodos['from']['periodo']." AND ".$periodos['to']['ano'].$periodos['to']['periodo']."
  1099.                     {$programa['where']}
  1100.                     {$whereFiltro}
  1101.                     {$gestor_permissoes}";
  1102.     
  1103.         $stmt $this->_em->getConnection()->prepare($sql);
  1104.         
  1105.         return $stmt->executeQuery()->fetchAssociative();
  1106.     }
  1107.     /**
  1108.      * Faz um count distinto da quantidade total de Avaliados, Indicadores, Grupos e, caso o $programa venha sem 'id_modelagem', Modelagens
  1109.      *  da tabela modelagem.scorecard_avaliados para ser utilizado nos alertas da visão Gestor e Gestor de Rede
  1110.      */
  1111.     public function findTotaisAlertasGestor(array $periodos, array $filtros, array $programa)
  1112.     {
  1113.         $whereFiltro '';
  1114.         if (count($filtros) > 0) {
  1115.             foreach ($filtros as $filtro) {
  1116.                 $whereFiltro .= $filtro ' ';
  1117.             }
  1118.         }
  1119.         $totalModelagens '';
  1120.         if (strstr($programa['where'], 'id_modelagem') == false) {
  1121.             $totalModelagens 'COUNT(DISTINCT id_modelagem) total_modelagens,';
  1122.         }
  1123.         $sql "SELECT
  1124.                     {$totalModelagens}
  1125.                     COUNT(DISTINCT id_avaliado) total_avaliados,
  1126.                     COUNT(DISTINCT id_indicador) total_indicadores,
  1127.                     COUNT(DISTINCT id_grupo) total_grupos
  1128.                 FROM
  1129.                     modelagem.scorecard_avaliados
  1130.                 JOIN LATERAL (
  1131.                     SELECT generate_periodo periodo FROM generate_periodo(%s,%s)
  1132.                 ) p ON p.periodo BETWEEN avaliacao_inicio AND avaliacao_fim AND p.periodo BETWEEN scorecard_inicio AND scorecard_fim
  1133.                 WHERE TRUE
  1134.                     {$programa['where']}
  1135.                     {$whereFiltro}";
  1136.         $sql sprintf($sql$periodos['from']['ano'] . $periodos['from']['periodo'], $periodos['to']['ano'] . $periodos['to']['periodo']);
  1137.         $stmt $this->_em->getConnection()->prepare($sql);
  1138.         
  1139.         return $stmt->executeQuery()->fetchAssociative();
  1140.     }
  1141.     /**
  1142.      * Faz um count da quantidade de avaliados que estão abaixo da nota de corte setada na sessão
  1143.      */
  1144.     public function findQtdAvaliadosAbaixoNotaCorte(array $periodos, array $filtros, array $programa, ?string $gestor_permissoes null)
  1145.     {
  1146.         $notaCorte $this->session->get('nota_corte');
  1147.         $whereFiltro '';
  1148.         if (count($filtros) > 0) {
  1149.             foreach ($filtros as $filtro) {
  1150.                 $whereFiltro .= $filtro ' ';
  1151.             }
  1152.         }
  1153.         $sql "SELECT
  1154.                     COUNT(id_avaliado) abaixo_avaliados
  1155.                 FROM (
  1156.                     SELECT
  1157.                         id_avaliado,
  1158.                         AVG(%s) %s
  1159.                     FROM dados.%s
  1160.                     WHERE TRUE
  1161.                         {$periodos['where']}
  1162.                         {$programa['where']}
  1163.                         {$whereFiltro}
  1164.                         {$gestor_permissoes}
  1165.                     GROUP BY 1
  1166.                 ) a
  1167.                 WHERE TRUE
  1168.                     %s";
  1169.         $sql sprintf($sql$notaCorte['campo'], $notaCorte['campo'], $notaCorte['tabela'], $notaCorte['where']['abaixo']);
  1170.         $stmt $this->_em->getConnection()->prepare($sql);
  1171.         
  1172.         return $stmt->executeQuery()->fetchOne();
  1173.     }
  1174.     /**
  1175.      * Faz um count da quantidade de avaliados que estão abaixo da nota de corte setada na sessão
  1176.      */
  1177.     public function findQtdGruposAbaixoNotaCorte(array $periodos, array $filtroSemAvaliado, array $programa, ?string $gestor_permissoes null)
  1178.     {
  1179.         $notaCorte $this->session->get('nota_corte');
  1180.         $sql "SELECT
  1181.                     COUNT(id_grupo) abaixo_grupos
  1182.                 FROM (
  1183.                     SELECT
  1184.                         id_grupo,
  1185.                         AVG(%s) %s
  1186.                     FROM dados.%s
  1187.                     WHERE TRUE
  1188.                         {$periodos['where']}
  1189.                         {$programa['where']}
  1190.                         %s
  1191.                         {$gestor_permissoes}
  1192.                     GROUP BY 1
  1193.                 ) a
  1194.                 WHERE TRUE
  1195.                     %s";
  1196.         $sql sprintf($sql$notaCorte['campo'], $notaCorte['campo'], $notaCorte['tabela'], $filtroSemAvaliado[0] ?? ''$notaCorte['where']['abaixo']);
  1197.         $stmt $this->_em->getConnection()->prepare($sql);
  1198.         
  1199.         return $stmt->executeQuery()->fetchOne();
  1200.     }
  1201.     public function findQtdModelagensAbaixoNotaCorte(array $periodos, array $programa)
  1202.     {
  1203.         $notaCorte $this->session->get('nota_corte');
  1204.         $sql "SELECT
  1205.                     COUNT(id_modelagem) abaixo_modelagens
  1206.                 FROM (
  1207.                     SELECT
  1208.                         id_modelagem,
  1209.                         AVG(%s) %s
  1210.                     FROM dados.%s
  1211.                     WHERE TRUE
  1212.                         {$periodos['where']}
  1213.                         {$programa['where']}
  1214.                     GROUP BY 1
  1215.                 ) a
  1216.                 WHERE TRUE
  1217.                     %s";
  1218.         $sql sprintf($sql$notaCorte['campo'], $notaCorte['campo'], $notaCorte['tabela'], $notaCorte['where']['abaixo']);
  1219.         $stmt $this->_em->getConnection()->prepare($sql);
  1220.         
  1221.         return $stmt->executeQuery()->fetchOne();
  1222.     }
  1223.     /**
  1224.      * @deprecated Ver TIDEV-68
  1225.      * @return array
  1226.      */
  1227.     public function findQtdAvaliadosGruposIndicadores(array $periodos, array $filtros, array $programa, array $filtroSemAvaliado)
  1228.     {
  1229.         $whereFiltro '';
  1230.         if (count($filtros) > 0) {
  1231.             foreach ($filtros as $filtro) {
  1232.                 $whereFiltro .= $filtro ' ';
  1233.             }
  1234.         }
  1235.         $notaCorte $this->session->get('nota_corte');
  1236.         $countModelagens '';
  1237.         $totalModelagens '';
  1238.         $abaixoModelagens '';
  1239.         $groupBy 'id_modelagem';
  1240.         if (strstr($programa['where'], 'id_modelagem') == false) {
  1241.             $countModelagens 'COUNT(DISTINCT id_modelagem) qtd_modelagens,';
  1242.             $totalModelagens 'COUNT(DISTINCT id_modelagem) total_modelagens,';
  1243.             $abaixoModelagens "JOIN LATERAL (
  1244.                 SELECT
  1245.                     COUNT(id_modelagem) abaixo_modelagens
  1246.                 FROM (
  1247.                     SELECT
  1248.                         id_modelagem,
  1249.                         AVG(performance) performance
  1250.                     FROM dados.gps
  1251.                     WHERE TRUE
  1252.                         {$periodos['where']}
  1253.                         {$programa['where']}
  1254.                     GROUP BY 1
  1255.                 ) a
  1256.                 WHERE TRUE
  1257.                     {$notaCorte['where']['abaixo']}
  1258.             ) am ON TRUE";
  1259.             $groupBy 'id_programa';
  1260.         }
  1261.         
  1262.         $sql sprintf("SELECT
  1263.                             *
  1264.                         FROM (
  1265.                             SELECT
  1266.                                 {$countModelagens}
  1267.                                 COUNT(DISTINCT id_avaliado) qtd_avaliados,
  1268.                                 COUNT(DISTINCT id_indicador) qtd_indicadores,
  1269.                                 COUNT(DISTINCT id_grupo) qtd_grupos
  1270.                             FROM
  1271.                                 dados.calculo c
  1272.                             WHERE TRUE
  1273.                                 {$periodos['where']}
  1274.                                 {$programa['where']}
  1275.                                 {$whereFiltro}
  1276.                             GROUP BY
  1277.                                 $groupBy
  1278.                         ) a
  1279.                         JOIN LATERAL (
  1280.                             SELECT
  1281.                                 {$totalModelagens}
  1282.                                 COUNT(DISTINCT id_avaliado) total_avaliados,
  1283.                                 COUNT(DISTINCT id_indicador) total_indicadores,
  1284.                                 COUNT(DISTINCT id_grupo) total_grupos
  1285.                             FROM
  1286.                                 modelagem.scorecard_avaliados
  1287.                             JOIN LATERAL (
  1288.                                 SELECT generate_periodo periodo FROM generate_periodo(%s,%s)
  1289.                             ) p ON periodo BETWEEN avaliacao_inicio AND avaliacao_fim
  1290.                             WHERE TRUE
  1291.                                 {$programa['where']}
  1292.                                 {$whereFiltro}
  1293.                         ) b ON TRUE
  1294.                         JOIN LATERAL (
  1295.                             SELECT
  1296.                                 COUNT(id_avaliado) abaixo_avaliados
  1297.                             FROM (
  1298.                                 SELECT
  1299.                                     id_avaliado,
  1300.                                     AVG(%s) %s
  1301.                                 FROM dados.%s
  1302.                                 WHERE TRUE
  1303.                                     {$periodos['where']}
  1304.                                     {$programa['where']}
  1305.                                     {$whereFiltro}
  1306.                                 GROUP BY 1
  1307.                             ) a
  1308.                             WHERE TRUE
  1309.                                 %s
  1310.                         ) aa ON TRUE
  1311.                         JOIN LATERAL (
  1312.                             SELECT
  1313.                                 COUNT(id_grupo) abaixo_grupos
  1314.                             FROM (
  1315.                                 SELECT
  1316.                                     id_grupo,
  1317.                                     AVG(%s) %s
  1318.                                 FROM dados.%s
  1319.                                 WHERE TRUE
  1320.                                     {$periodos['where']}
  1321.                                     {$programa['where']}
  1322.                                     %s
  1323.                                 GROUP BY 1
  1324.                             ) a
  1325.                             WHERE TRUE
  1326.                                 %s
  1327.                         ) ag ON TRUE
  1328.                         $abaixoModelagens
  1329.                         ",
  1330.                         $periodos['from']['ano'] . $periodos['from']['periodo'],
  1331.                         $periodos['to']['ano'] . $periodos['to']['periodo'],
  1332.                         $notaCorte['campo'],
  1333.                         $notaCorte['campo'],
  1334.                         $notaCorte['tabela'],
  1335.                         $notaCorte['where']['abaixo'],
  1336.                         $notaCorte['campo'],
  1337.                         $notaCorte['campo'],
  1338.                         $notaCorte['tabela'],
  1339.                         $filtroSemAvaliado[0] ?? '',
  1340.                         $notaCorte['where']['abaixo']
  1341.                     );
  1342.         $stmt $this->_em->getConnection()->prepare($sql);
  1343.         
  1344.         return $stmt->executeQuery()->fetchAllAssociative();
  1345.     }
  1346.     public function getCorrelacaoIndicadores(int $id_modelagemint $id_grupoint $periodo): array
  1347.     {
  1348.         $sql "SELECT
  1349.                     indicador_1 AS indicador,
  1350.                     nome_indicador_1 AS nome_indicador,
  1351.                     jsonb_agg(correlacao) correlacoes
  1352.                 FROM (
  1353.                     SELECT
  1354.                         id_modelagem,
  1355.                         id_grupo,
  1356.                         indicador_1,
  1357.                         nome_indicador_1,
  1358.                         indicador_2,
  1359.                         nome_indicador_2,
  1360.                         corr(performance_1, performance_2) correlacao
  1361.                     FROM (
  1362.                         SELECT
  1363.                             id_modelagem,
  1364.                             id_grupo,
  1365.                             id_avaliado,
  1366.                             a.id_indicador AS indicador_1,
  1367.                             a.nome_indicador AS nome_indicador_1,
  1368.                             a.performance AS performance_1,
  1369.                             d.id_indicador AS indicador_2,
  1370.                             d.performance AS performance_2,
  1371.                             a.nome_indicador AS nome_indicador_2
  1372.                         FROM (
  1373.                             SELECT
  1374.                                 id_modelagem,
  1375.                                 id_grupo,
  1376.                                 id_avaliado,
  1377.                                 id_indicador,
  1378.                                 nome_indicador,
  1379.                                 AVG(performance) performance
  1380.                             FROM dados.calculo
  1381.                             WHERE id_modelagem = {$id_modelagem} AND id_grupo = {$id_grupo}
  1382.                                 AND CONCAT(periodo->>'ano', periodo->>'periodo')::integer = {$periodo}
  1383.                             GROUP BY 1,2,3,4,5
  1384.                         ) a
  1385.                         JOIN LATERAL(
  1386.                             SELECT
  1387.                                 id_indicador,
  1388.                                 nome_indicador,
  1389.                                 AVG(performance) performance
  1390.                             FROM dados.calculo c
  1391.                             WHERE c.id_modelagem = a.id_modelagem AND c.id_grupo = a.id_grupo AND c.id_avaliado = a.id_avaliado
  1392.                                 AND CONCAT(periodo->>'ano', periodo->>'periodo')::integer = {$periodo}
  1393.                             GROUP BY id_modelagem, id_grupo, id_avaliado, 1,2
  1394.                         ) d ON true
  1395.                         ORDER BY 1,2,3,4,7
  1396.                     ) b
  1397.                     GROUP BY 1,2,3,4,5,6
  1398.                 ) c
  1399.                 GROUP BY 1,2";
  1400.         $stmt $this->_em->getConnection()->prepare($sql);
  1401.         
  1402.         return $stmt->executeQuery()->fetchAllAssociative();
  1403.     }
  1404.     /**
  1405.      * @param array|null $filtro
  1406.      * @return array
  1407.      */
  1408.     public function findCalculos(?array $filtro, ?bool $count false, ?int $limit null, ?int $offset null)
  1409.     {
  1410.         $alias = !is_null($filtro['sem_resultado']) ? 'a.' 'b.';
  1411.         $arrayFiltro = [
  1412.             'id_modelagem' => " AND b.id_modelagem IN (%s)",
  1413.             'id_grupo' => " AND b.id_grupo IN (%s)",
  1414.             'id_avaliado' => " AND b.id_avaliado IN (%s)"
  1415.         ];
  1416.         $now = new DateTime('America/Sao_Paulo');
  1417.         $filtro['data_inicio'] = !empty($filtro['data_inicio']) ? str_replace("/"""$filtro['data_inicio']) : 199001;
  1418.         $filtro['data_fim'] = !empty($filtro['data_fim']) ? str_replace("/"""$filtro['data_fim']) : $now->format('Ym');
  1419.         
  1420.         $sql '';
  1421.         $sql .= "SELECT
  1422.                     {$alias}id_programa
  1423.                     , {$alias}nome_programa
  1424.                     , {$alias}id_modelagem
  1425.                     , {$alias}nome_modelagem
  1426.                     , {$alias}id_dominio
  1427.                     , {$alias}nome_dominio
  1428.                     , {$alias}id_grupo
  1429.                     , {$alias}nome_grupo
  1430.                     , {$alias}id_avaliado
  1431.                     , {$alias}nome_avaliado
  1432.                     , {$alias}id_indicador
  1433.                     , {$alias}nome_indicador
  1434.                     , {$alias}unidade_indicador AS unidade
  1435.                     , dados
  1436.                     , REPLACE(numerador::text, '.', ',') AS numerador
  1437.                     , REPLACE(denominador::text, '.', ',') AS denominador
  1438.                     , REPLACE(valor::text, '.', ',') AS resultado
  1439.                     , REPLACE({$alias}peso::text, '.', ',') AS peso
  1440.                     , REPLACE(COALESCE(score, 0)::text, '.', ',') AS score
  1441.                     , periodo.periodo
  1442.                 FROM generate_periodo(:data_inicio, :data_fim) periodo";
  1443.         if (!is_null($filtro['sem_resultado'])) {
  1444.             $sql .= "\nJOIN LATERAL (
  1445.                         SELECT 
  1446.                             DISTINCT id_programa
  1447.                             , nome_programa
  1448.                             , id_modelagem
  1449.                             , nome_modelagem
  1450.                             , id_dominio
  1451.                             , nome_dominio
  1452.                             , id_grupo
  1453.                             , nome_grupo
  1454.                             , id_avaliado
  1455.                             , nome_avaliado
  1456.                             , id_indicador
  1457.                             , nome_indicador
  1458.                             , unidade_indicador
  1459.                             , peso
  1460.                         FROM modelagem.scorecard_avaliados 
  1461.                         WHERE avaliacao_fim BETWEEN :data_inicio and :data_fim %s
  1462.                     ) a ON TRUE";
  1463.         }
  1464.         $sql .= "\nLEFT JOIN dados.calculo b ON
  1465.                     CONCAT(b.periodo->>'ano',b.periodo->>'periodo') = periodo.periodo::text
  1466.                     %s";
  1467.         $where '';
  1468.         if (!is_null($filtro)) {
  1469.             foreach ($filtro as $key => $content) {
  1470.                 if ( !empty($content) && in_array($keyarray_keys($arrayFiltro))) {
  1471.                     if (is_array($content)) {
  1472.                         $filtro[$key] = implode(', '$content);
  1473.                     }
  1474.                     $where .= sprintf($arrayFiltro[$key], $filtro[$key]);
  1475.                 }
  1476.             }
  1477.         }
  1478.         if ( !is_null($filtro['sem_resultado']) ) {
  1479.             $sql .= "\nAND a.id_programa = b.id_programa
  1480.                     AND a.id_modelagem = b.id_modelagem
  1481.                     AND a.id_dominio = b.id_dominio
  1482.                     AND a.id_grupo = b.id_grupo
  1483.                     AND a.id_avaliado = b.id_avaliado
  1484.                     AND a.id_indicador = b.id_indicador";
  1485.         }
  1486.         if ( !is_null($filtro['sem_resultado']) ) {
  1487.             $sql sprintf($sqlstr_replace('b.'''$where), $where);
  1488.         } else {
  1489.             $sql sprintf($sql$where);
  1490.         }
  1491.         $sql .= "\nORDER BY {$alias}id_avaliado, periodo, dados NULLS LAST
  1492.                  %s";
  1493.         $sql sprintf($sql, (!is_null($limit) ? "LIMIT $limit OFFSET $offset''));
  1494.         if ( $count ) {
  1495.             $sql sprintf("SELECT COUNT(*) AS rows FROM (%s) c"$sql);
  1496.         }
  1497.         $stmt $this->_em->getConnection()->prepare($sql);
  1498.         $stmt->bindParam(':data_inicio'$filtro['data_inicio'], ParameterType::INTEGER);
  1499.         $stmt->bindParam(':data_fim'$filtro['data_fim'], ParameterType::INTEGER);
  1500.         return $stmt->executeQuery()->fetchAllAssociative();
  1501.     }
  1502.     /**
  1503.      * @param array|null $filtro
  1504.      * @return array
  1505.      */
  1506.     public function gerarBandaHistoricaDecil()
  1507.     {
  1508.         
  1509.         $sql "SELECT
  1510.                     id_indicador
  1511.                     , nome_indicador
  1512.                     , interpretacao
  1513.                     , jsonb_agg(jsonb_build_object((percentil * 100)::int, valor) ORDER BY (percentil * 100)::int ASC)
  1514.                 FROM generate_series(0,1,0.1) percentil
  1515.                 JOIN LATERAL(
  1516.                     SELECT 
  1517.                         id_indicador
  1518.                         , nome_indicador
  1519.                         , ficha_tecnica->>'interpretacao' interpretacao
  1520.                         , CASE WHEN ficha_tecnica->>'interpretacao' = 'MENOR' THEN percentile_cont(percentil) WITHIN GROUP (ORDER BY valor DESC) ELSE percentile_cont(percentil) WITHIN GROUP (ORDER BY valor ASC) END valor
  1521.                     FROM dados.calculo
  1522.                     JOIN modelagem.indicador USING(id_indicador)
  1523.                     GROUP BY 1,2,3, ficha_tecnica
  1524.                 ) a ON TRUE
  1525.                 --WHERE interpretacao IS NOT NULL
  1526.                 GROUP BY 1,2,3
  1527.                 ORDER BY 1,2";
  1528.         $stmt $this->_em->getConnection()->prepare($sql);
  1529.         return $stmt->executeQuery()->fetchAllAssociative();
  1530.     }
  1531.     public function findModelagensWithCountGruposAvaliadosIndicadores(array $periodos, array $programastring $gestor_permissoes)
  1532.     {
  1533.         $sql "SELECT
  1534.                     id_modelagem,
  1535.                     nome_modelagem,
  1536.                     COUNT(DISTINCT id_grupo) qtd_grupos,
  1537.                     COUNT(DISTINCT id_avaliado) qtd_avaliados,
  1538.                     COUNT(DISTINCT id_indicador) qtd_indicadores
  1539.                 FROM dados.calculo
  1540.                 WHERE TRUE
  1541.                     {$periodos['where']}
  1542.                     {$programa['where']}
  1543.                     {$gestor_permissoes}
  1544.                 GROUP BY 1,2";
  1545.         $stmt $this->_em->getConnection()->prepare($sql);
  1546.         
  1547.         return $stmt->executeQuery()->fetchAllAssociative();
  1548.     }
  1549.     public function findMediasPerformanceAbsolutoAnual(array $programaint $idIndicadorstring $ano, ?array $especialidade null)
  1550.     {
  1551.         $whereGrupo null;
  1552.         if (!is_null($especialidade)) {
  1553.             $whereGrupo ' AND id_grupo = ' $especialidade['id'];
  1554.         }
  1555.         $sql "SELECT
  1556.                     id_indicador,
  1557.                     nome_indicador,
  1558.                     unidade_indicador,
  1559.                     JSONB_AGG(
  1560.                         JSONB_BUILD_OBJECT(
  1561.                             'periodo', periodo,
  1562.                             'performance', performance,
  1563.                             'absoluto', absoluto,
  1564.                             'qtd_avaliados', qtd_avaliados
  1565.                         )
  1566.                     ) periodos
  1567.                 FROM (
  1568.                     SELECT
  1569.                         id_indicador,
  1570.                         nome_indicador,
  1571.                         unidade_indicador,
  1572.                         CONCAT(periodo->>'ano', periodo->>'periodo')::integer periodo,
  1573.                         ROUND(AVG(performance), 2) performance,
  1574.                         ROUND(AVG(valor), 2) absoluto,
  1575.                         COUNT(DISTINCT id_avaliado) qtd_avaliados
  1576.                     FROM dados.calculo
  1577.                     WHERE CONCAT(periodo->>'ano', periodo->>'periodo')::integer BETWEEN %s AND %s
  1578.                         {$programa['where']}
  1579.                         {$whereGrupo}
  1580.                         AND id_indicador = {$idIndicador}
  1581.                     GROUP BY 1,2,3,4
  1582.                     ORDER BY periodo
  1583.                 ) a
  1584.                 GROUP BY 1,2,3";
  1585.         $sql sprintf($sqlexplode('-'$ano)[0], explode('-'$ano)[1]);
  1586.         $stmt $this->_em->getConnection()->prepare($sql);
  1587.         
  1588.         return $stmt->executeQuery()->fetchAssociative();
  1589.     }
  1590.     public function getMediaSomaScore(array $periodos, ?array $param null)
  1591.     {
  1592.         $selectJSON ", nome_dominio";
  1593.         if ( isset($param['filter_avaliado']) ) {
  1594.             $selectJSON ", CONCAT(nome_avaliado, ' - ', nome_dominio)";
  1595.         }
  1596.         if ( isset($param['filter_grupo']) ) {
  1597.             $selectJSON ", CONCAT(nome_grupo, ' - ', nome_dominio)";
  1598.         }
  1599.         $avaliadoSQL['select'] = isset($param['filter_avaliado']) ? ', id_avaliado, nome_avaliado' '';
  1600.         $avaliadoSQL['where'] = isset($param['filter_avaliado']) ? " AND id_avaliado IN ({$param['avaliados']})" "";
  1601.         $avaliadoSQL['orderBy'] = isset($param['filter_avaliado']) ? 'nome_avaliado, ' '';
  1602.         $dominioSQL['where'] = !empty($param['dominios']) ? " AND id_dominio IN ({$param['dominios']})" "";
  1603.         $grupoSQL['select'] = isset($param['filter_grupo']) ? !empty($param['especialidades']) ? ', nome_grupo' '' '';
  1604.         $grupoSQL['where'] = isset($param['filter_grupo']) ? !empty($param['especialidades']) ? " AND id_grupo IN ({$param['especialidades']})" "" "";
  1605.         $grupoSQL['orderBy'] = isset($param['filter_grupo']) ? 'nome_grupo, ' '';
  1606.         $sql "SELECT
  1607.                     ROUND( AVG(performance) FILTER(WHERE soma_score IS NOT NULL), 2) media_scores,
  1608.                     id_dominio
  1609.                     $selectJSON AS nome_dominio,
  1610.                     periodo
  1611.                     {$avaliadoSQL['select']}
  1612.                     {$grupoSQL['select']}
  1613.                 FROM (
  1614.                     SELECT
  1615.                         COALESCE(b.soma_score, 0) soma_score,
  1616.                         CASE
  1617.                             WHEN soma_score IS NOT NULL THEN ((soma_score / soma_peso) * 100)
  1618.                             ELSE null
  1619.                         END performance,
  1620.                         b.id_dominio,
  1621.                         b.nome_dominio,
  1622.                         b.periodo
  1623.                         {$avaliadoSQL['select']}
  1624.                         {$grupoSQL['select']}
  1625.                     FROM (
  1626.                         SELECT
  1627.                             SUM(a.score) AS soma_score,
  1628.                             SUM(a.peso) AS soma_peso,
  1629.                             a.periodo,
  1630.                             a.id_dominio,
  1631.                             a.nome_dominio
  1632.                             {$avaliadoSQL['select']}
  1633.                             {$grupoSQL['select']}
  1634.                         FROM (
  1635.                             SELECT
  1636.                                 {$periodos['select']},
  1637.                                 score,
  1638.                                 ROUND(AVG(peso), 2) peso,
  1639.                                 id_dominio,
  1640.                                 nome_dominio
  1641.                                 {$avaliadoSQL['select']}
  1642.                                 {$grupoSQL['select']}
  1643.                             FROM dados.calculo
  1644.                             WHERE TRUE {$dominioSQL['where']}{$periodos['where']}{$avaliadoSQL['where']}{$grupoSQL['where']}
  1645.                             GROUP BY periodo, id_dominio, nome_dominio, score{$avaliadoSQL['select']}{$grupoSQL['select']}
  1646.                         ) a
  1647.                         GROUP BY a.periodo, a.id_dominio, a.nome_dominio{$avaliadoSQL['select']}{$grupoSQL['select']}
  1648.                         ORDER BY {$avaliadoSQL['orderBy']}{$grupoSQL['orderBy']}a.id_dominio, a.periodo
  1649.                     ) b
  1650.                 ) c
  1651.                 GROUP BY c.periodo, c.id_dominio, c.soma_score, c.nome_dominio{$avaliadoSQL['select']}{$grupoSQL['select']}
  1652.                 ORDER BY {$avaliadoSQL['orderBy']}{$grupoSQL['orderBy']}c.id_dominio, c.periodo";
  1653.         $stmt $this->_em->getConnection()->prepare($sql);
  1654.         return $stmt->executeQuery()->fetchAllAssociative();
  1655.     }
  1656.     public function getAvaliados($grupos nullint $id_modelagem)
  1657.     {
  1658.         $sql sprintf(
  1659.                     "SELECT
  1660.                         DISTINCT(id_avaliado) AS id_avaliado,
  1661.                         nome_avaliado,
  1662.                         id_grupo,
  1663.                         nome_grupo AS grupo
  1664.                     FROM dados.calculo
  1665.                     WHERE TRUE %s AND id_modelagem = {$id_modelagem}
  1666.                     ORDER BY id_grupo",
  1667.                     $grupos sprintf('AND id_grupo IN(%s)'filter_var($gruposFILTER_SANITIZE_STRING)) : ''
  1668.                 );
  1669.         $stmt $this->_em->getConnection()->prepare($sql);
  1670.         return $stmt->executeQuery()->fetchAllAssociative();
  1671.     }
  1672.     public function findDominios(int $id_modelagem)
  1673.     {
  1674.         $sql "SELECT DISTINCT id_dominio,
  1675.                     nome_dominio AS titulo
  1676.                 FROM dados.calculo
  1677.                 WHERE id_modelagem = {$id_modelagem}
  1678.                 ORDER BY 1";
  1679.         $stmt $this->_em->getConnection()->prepare($sql);
  1680.         return $stmt->executeQuery()->fetchAllAssociative();
  1681.     }
  1682.     public function findGrupos(int $id_modelagem)
  1683.     {
  1684.         $sql "SELECT
  1685.                     DISTINCT id_grupo,
  1686.                     nome_grupo AS titulo
  1687.                 FROM dados.calculo
  1688.                 WHERE id_modelagem = {$id_modelagem}
  1689.                 ORDER BY 1";
  1690.         $stmt $this->_em->getConnection()->prepare($sql);
  1691.         return $stmt->executeQuery()->fetchAllAssociative();
  1692.     }
  1693.     public function findIndicadores(int $idModelagem, ?int $idBusca null)
  1694.     {
  1695.         $whereGrupo '';
  1696.         if (!is_null($idBusca) && $idBusca != 0) {
  1697.             $whereGrupo " AND id_grupo = {$idBusca}";
  1698.         }
  1699.         $sql "SELECT DISTINCT
  1700.                     id_indicador,
  1701.                     nome_indicador
  1702.                 FROM dados.calculo
  1703.                 WHERE id_modelagem = {$idModelagem}
  1704.                     {$whereGrupo}";
  1705.         $stmt $this->_em->getConnection()->prepare($sql);
  1706.         
  1707.         return $stmt->executeQuery()->fetchAllAssociative();
  1708.     }
  1709.     public function findIndicadoresWithoutModelagem(?int $idBusca null)
  1710.     {
  1711.         $whereGrupo '';
  1712.         if (!is_null($idBusca) && $idBusca != 0) {
  1713.             $whereGrupo " AND id_grupo = {$idBusca}";
  1714.         }
  1715.         $sql "SELECT DISTINCT
  1716.                     id_indicador,
  1717.                     nome_indicador
  1718.                 FROM dados.calculo
  1719.                 WHERE TRUE
  1720.                     {$whereGrupo}";
  1721.         $stmt $this->_em->getConnection()->prepare($sql);
  1722.         
  1723.         return $stmt->executeQuery()->fetchAllAssociative();
  1724.     }
  1725.     public function findPerformanceIndicadorAvaliado(array $periodoint $idModelagemint $idIndicador, ?int $idBusca nullbool $evs true)
  1726.     {
  1727.         $toChar '990D99%';
  1728.         $alias 'evs';
  1729.         $campo 'performance';
  1730.         if (!$evs) {
  1731.             $alias 'gps';
  1732.         }
  1733.         $whereGrupo "";
  1734.         if (!is_null($idBusca) && $idBusca != 0) {
  1735.             $whereGrupo " AND id_grupo = {$idBusca}";
  1736.         }
  1737.         $sql "SELECT
  1738.                     id_avaliado,
  1739.                     nome_avaliado,
  1740.                     id_grupo,
  1741.                     nome_grupo,
  1742.                     CONCAT(periodo->>'ano', periodo->>'periodo')::integer periodo,
  1743.                     {$campo} {$alias},
  1744.                     Trim(To_Char({$campo}, '{$toChar}')) {$alias}_txt,
  1745.                     Round(Avg({$campo}) OVER(PARTITION BY id_grupo, id_avaliado), 2) AS {$alias}_anual,
  1746.                     Trim(To_Char(Round(Avg({$campo}) OVER(PARTITION BY id_grupo, id_avaliado), 2), '{$toChar}')) AS {$alias}_anual_txt,
  1747.                     true is_producao,
  1748.                     Substring(CONCAT(periodo->>'ano', periodo->>'periodo')::text,5,2)::integer periodo_mes,
  1749.                     To_Char(((CONCAT(periodo->>'ano', periodo->>'periodo'))::text||'01')::date,'MM')::int periodo_txt
  1750.                 FROM dados.calculo
  1751.                 WHERE TRUE
  1752.                     AND id_modelagem = {$idModelagem}
  1753.                     AND id_indicador = {$idIndicador}
  1754.                     {$periodo['where']}
  1755.                     {$whereGrupo}
  1756.                 ORDER BY {$alias}_anual DESC, CONCAT(periodo->>'ano', periodo->>'periodo')::integer, id_avaliado";
  1757.         $stmt $this->_em->getConnection()->prepare($sql);
  1758.         
  1759.         return $stmt->executeQuery();
  1760.     }
  1761.     public function findPerformanceIndicadorEspecialidade(array $periodoint $idModelagemint $idIndicador, ?int $idBusca nullbool $evs true)
  1762.     {
  1763.         $toChar '990D99%';
  1764.         $alias 'evs';
  1765.         $campo 'performance';
  1766.         if (!$evs) {
  1767.             $alias 'gps';
  1768.         }
  1769.         $whereGrupo "";
  1770.         if (!is_null($idBusca) && $idBusca != 0) {
  1771.             $whereGrupo " AND id_grupo = {$idBusca}";
  1772.         }
  1773.         $sql "SELECT
  1774.                       {$alias}.id_grupo
  1775.                     , MAX({$alias}.nome_grupo) AS nome_grupo
  1776.                     , {$alias}.periodo
  1777.                     , ROUND(AVG({$alias}.{$alias}), 2) AS {$alias}
  1778.                     , TRIM(TO_CHAR(ROUND(AVG({$alias}.{$alias}), 2), '{$toChar}')) AS {$alias}_txt
  1779.                     , ROUND(AVG({$alias}.{$alias}_anual), 2) AS {$alias}_anual
  1780.                     , MAX({$alias}.{$alias}_anual_txt) AS {$alias}_anual_txt
  1781.                     , SUBSTRING({$alias}.periodo::text, 5, 2)::integer periodo_mes
  1782.                     , TO_CHAR((({$alias}.periodo)::text || '01')::date, 'MM')::int periodo_txt
  1783.                 FROM (
  1784.                     SELECT
  1785.                         id_grupo,
  1786.                         nome_grupo,
  1787.                         CONCAT(periodo->>'ano', periodo->>'periodo')::integer periodo,
  1788.                         {$campo} {$alias},
  1789.                         ROUND(AVG({$campo}) OVER(PARTITION BY id_grupo), 2) AS {$alias}_anual,
  1790.                         TRIM(TO_CHAR(ROUND(AVG({$campo}) OVER(PARTITION BY id_grupo), 2), '{$toChar}')) AS {$alias}_anual_txt,
  1791.                         true is_producao,
  1792.                         SUBSTRING(CONCAT(periodo->>'ano', periodo->>'periodo')::text,5,2)::integer periodo_mes,
  1793.                         TO_CHAR(((CONCAT(periodo->>'ano', periodo->>'periodo'))::text||'01')::date,'MM')::int periodo_txt
  1794.                     FROM dados.calculo
  1795.                     WHERE TRUE
  1796.                         AND id_modelagem = {$idModelagem}
  1797.                         AND id_indicador = {$idIndicador}
  1798.                         {$periodo['where']}
  1799.                         {$whereGrupo}
  1800.                 ) {$alias}
  1801.                 GROUP BY id_grupo, periodo
  1802.                 ORDER BY {$alias}.id_grupo, {$alias}.periodo
  1803.         ";
  1804.         $stmt $this->_em->getConnection()->prepare($sql);
  1805.         return $stmt->executeQuery();
  1806.     }
  1807.     public function findAvaliadosSemProducao(array $periodoint $idModelagemint $idIndicador, ?int $idBusca nullbool $evs true)
  1808.     {
  1809.         $toChar '990D99%';
  1810.         $alias 'evs';
  1811.         $campo 'performance';
  1812.         if (!$evs) {
  1813.             $alias 'gps';
  1814.         }
  1815.         $whereGrupo "";
  1816.         if (!is_null($idBusca) && $idBusca != 0) {
  1817.             $whereGrupo " AND id_grupo = {$idBusca}";
  1818.         }
  1819.         
  1820.         $sql "select 
  1821.                     *
  1822.                 from (
  1823.                     select 
  1824.                         a.id_avaliado
  1825.                         , a.nome_avaliado
  1826.                         , a.id_grupo
  1827.                         , a.nome_grupo
  1828.                         , jsonb_agg(DISTINCT CASE WHEN CONCAT(periodo->>'ano',periodo->>'periodo') <> '' THEN CONCAT(periodo->>'ano',periodo->>'periodo') END) periodos
  1829.                     from modelagem.scorecard_avaliados a
  1830.                     left join dados.evs b ON a.id_programa = b.id_programa AND a.id_modelagem = b.id_modelagem AND a.id_grupo = b.id_grupo AND a.id_avaliado = b.id_avaliado AND CONCAT(periodo->>'ano',periodo->>'periodo')::int BETWEEN ".$periodo['from']['ano'].$periodo['from']['periodo']." AND ".$periodo['to']['ano'].$periodo['to']['periodo']."
  1831.                     WHERE ".$periodo['from']['ano'].$periodo['from']['periodo']." BETWEEN avaliacao_inicio AND avaliacao_fim AND ".$periodo['to']['ano'].$periodo['to']['periodo']." BETWEEN avaliacao_inicio AND avaliacao_fim
  1832.                     GROUP BY 1,2,3,4
  1833.                 ) a
  1834.                 WHERE periodos = '[null]'::jsonb
  1835.                 ORDER BY 4";
  1836.                 
  1837.         $stmt $this->_em->getConnection()->prepare($sql);
  1838.         return $stmt->executeQuery();
  1839.     }
  1840.     public function findPerformanceIndicadorEspecialidadeFesp(array $periodoint $idModelagemint $idIndicador, ?int $idBusca nullbool $evs true)
  1841.     {
  1842.         $sql "select 
  1843.                 id_modelagem
  1844.                 , nome_modelagem
  1845.                 , id_grupo
  1846.                 , nome_grupo
  1847.                 , CONCAT(periodo->>'ano',periodo->>'periodo') As periodo
  1848.                 , CONCAT(periodo->>'periodo', '/', periodo->>'ano') AS periodo_txt
  1849.                 , REPLACE(ROUND(AVG(valor), 2)::text, '.', ',') AS evs
  1850.             from dados.evs
  1851.             WHERE TRUE {$periodo['where']}
  1852.             GROUP BY 1,2,3,4,5,6
  1853.             order by 3,5";
  1854.         $stmt $this->_em->getConnection()->prepare($sql);
  1855.         return $stmt->executeQuery();
  1856.     }
  1857.     
  1858.     public function findPerformanceIndicadorAvaliadoRede(array $periodoint $idIndicador, ?int $idBusca nullbool $evs true)
  1859.     {
  1860.         $toChar '990D99%';
  1861.         $alias 'evs';
  1862.         $campo 'performance';
  1863.         if (!$evs) {
  1864.             $alias 'gps';
  1865.         }
  1866.         $whereGrupo "";
  1867.         if (!is_null($idBusca) && $idBusca != 0) {
  1868.             $whereGrupo " AND id_grupo = {$idBusca}";
  1869.         }
  1870.         $sql "SELECT
  1871.                     id_avaliado,
  1872.                     nome_avaliado,
  1873.                     id_grupo,
  1874.                     nome_grupo,
  1875.                     id_modelagem,
  1876.                     nome_modelagem,
  1877.                     CONCAT(periodo->>'ano', periodo->>'periodo')::integer periodo,
  1878.                     {$campo} {$alias},
  1879.                     Trim(To_Char({$campo}, '{$toChar}')) {$alias}_txt,
  1880.                     Round(Avg({$campo}) OVER(PARTITION BY id_grupo, id_modelagem, id_avaliado), 2) AS {$alias}_anual,
  1881.                     Trim(To_Char(Round(Avg({$campo}) OVER(PARTITION BY id_grupo, id_modelagem, id_avaliado), 2), '{$toChar}')) AS {$alias}_anual_txt,
  1882.                     true is_producao,
  1883.                     Substring(CONCAT(periodo->>'ano', periodo->>'periodo')::text,5,2)::integer periodo_mes,
  1884.                     To_Char(((CONCAT(periodo->>'ano', periodo->>'periodo'))::text||'01')::date,'MM')::int periodo_txt
  1885.                 FROM dados.calculo
  1886.                 WHERE TRUE
  1887.                     AND id_indicador = {$idIndicador}
  1888.                     {$periodo['where']}
  1889.                     {$whereGrupo}
  1890.                 ORDER BY {$alias}_anual DESC, CONCAT(periodo->>'ano', periodo->>'periodo')::integer, id_avaliado";
  1891.         $stmt $this->_em->getConnection()->prepare($sql);
  1892.         
  1893.         return $stmt->executeQuery();
  1894.     }
  1895.     public function findEvolucaoAnualIndicadorAvaliado(int $idAvaliadoint $idGrupoint $idModelagemint $idIndicador, array $periodostring $campo 'evs')
  1896.     {
  1897.         $sql "SELECT
  1898.                     id_avaliado,
  1899.                     nome_avaliado,
  1900.                     CONCAT(periodo->>'ano', periodo->>'periodo')::integer periodo,
  1901.                     ROUND(performance, 2) {$campo}
  1902.                 FROM dados.calculo
  1903.                 WHERE
  1904.                     id_avaliado = {$idAvaliado}
  1905.                     AND id_grupo = {$idGrupo}
  1906.                     AND id_modelagem = {$idModelagem}
  1907.                     AND id_indicador = {$idIndicador}
  1908.                     {$periodo['where']}";
  1909.         $stmt $this->_em->getConnection()->prepare($sql);
  1910.         
  1911.         return $stmt->executeQuery()->fetchAllAssociative();
  1912.     }
  1913.     public function findEvolucaoAnualIndicadorGrupo(int $idGrupoint $idModelagemint $idIndicador, array $periodostring $campo 'evs')
  1914.     {
  1915.         $sql "SELECT
  1916.                     id_grupo,
  1917.                     nome_grupo,
  1918.                     CONCAT(periodo->>'ano', periodo->>'periodo')::integer periodo,
  1919.                     ROUND(AVG(performance), 2) {$campo}
  1920.                 FROM dados.calculo
  1921.                 WHERE
  1922.                     id_grupo = {$idGrupo}
  1923.                     AND id_modelagem = {$idModelagem}
  1924.                     AND id_indicador = {$idIndicador}
  1925.                     {$periodo['where']}
  1926.                 GROUP BY 1,2,3";
  1927.         $stmt $this->_em->getConnection()->prepare($sql);
  1928.         
  1929.         return $stmt->executeQuery()->fetchAllAssociative();
  1930.     }
  1931.     /**
  1932.      * @return array
  1933.      */
  1934.     public function getDetalhesDesempenhoIndicadorRastreabilidade(int $id_indicadorint $periodo, array $filtros, array $programaint $id_avaliado)
  1935.     {
  1936.         $whereFiltro '';
  1937.         if (count($filtros) > 0) {
  1938.             foreach ($filtros as $filtro) {
  1939.                 $whereFiltro .= $filtro ' ';
  1940.             }
  1941.         }
  1942.         $sql "SELECT * FROM dados.rastreabilidade JOIN modelagem.indicador USING(id_indicador) WHERE id_indicador = %s AND id_avaliado = %s AND CONCAT(periodo->>'ano',periodo->>'periodo')::int = %s %s";
  1943.         $sql sprintf($sql$id_indicador$id_avaliado$periodo$programa['where']);
  1944.                             
  1945.         $stmt $this->_em->getConnection()->prepare($sql);
  1946.         return $stmt->executeQuery()->fetchAssociative();
  1947.     }
  1948.     /**
  1949.      * @return array
  1950.      */
  1951.     public function getDetalhesDesempenhoIndicadorRastreabilidadeDrg(int $id_indicadorint $periodo, array $filtros, array $programaint $id_avaliado)
  1952.     {
  1953.         $whereFiltro '';
  1954.         if (count($filtros) > 0) {
  1955.             foreach ($filtros as $filtro) {
  1956.                 $whereFiltro .= $filtro ' ';
  1957.             }
  1958.         }
  1959.         $sql "SELECT * FROM dados.rastreabilidade JOIN modelagem.indicador USING(id_indicador) WHERE id_indicador = %s AND id_avaliado = %s AND CONCAT(periodo->>'ano',periodo->>'periodo')::int = %s %s";
  1960.         $sql "SELECT 
  1961.                     * 
  1962.                 FROM dados.drg 
  1963.                 JOIN modelagem.indicador USING(id_indicador)
  1964.                 WHERE id_indicador = %s AND id_avaliado = %s AND CONCAT(periodo->>'ano',periodo->>'periodo')::int = %s %s";
  1965.         
  1966.         $sql sprintf($sql$id_indicador$id_avaliado$periodo$programa['where']);
  1967.         
  1968.         $stmt $this->_em->getConnection()->prepare($sql);
  1969.         return $stmt->executeQuery()->fetchAllAssociative();
  1970.     }
  1971.     /**
  1972.      * @return array
  1973.      */
  1974.     public function getCalculo(int $id_indicadorint $periodo, array $filtros, array $programaint $id_avaliado)
  1975.     {
  1976.         $whereFiltro '';
  1977.         if (count($filtros) > 0) {
  1978.             foreach ($filtros as $filtro) {
  1979.                 $whereFiltro .= $filtro ' ';
  1980.             }
  1981.         }
  1982.         $sql "SELECT * FROM dados.calculo JOIN modelagem.indicador USING(id_indicador) WHERE id_indicador = %s AND id_avaliado = %s AND CONCAT(periodo->>'ano',periodo->>'periodo')::int = %s %s";
  1983.         $sql sprintf($sql$id_indicador$id_avaliado$periodo$programa['where']);
  1984.                             
  1985.         $stmt $this->_em->getConnection()->prepare($sql);
  1986.         return $stmt->executeQuery()->fetchAssociative();
  1987.     }
  1988. }