<?php
namespace App\Controller\Visao\Gestor\Componentes;
use App\Controller\Componentes\ComponenteAbstract;
use App\Entity\Cliente\Dimensao;
use App\Helper\ColorHelper;
use App\Helper\DateHelper;
use App\Helper\PeriodoHelper;
use App\Repository\Cliente\Dados\CalculoRepository;
use App\Repository\Cliente\Modelagem\IndicadorRepository;
use App\Repository\Cliente\Rastreabilidade\RastreabilidadeRepository;
use Doctrine\DBAL\Driver\ResultStatement;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("gestor/distribuicao-indicadores")
*/
class DistribuicaoIdicadores extends ComponenteAbstract
{
const TEMPLATEBASE = 'visao/gestor/componentes/';
/**
* @var CalculoRepository
*/
private $calculoRepository;
private $indicadorRepository;
private $rastreabilidadeRepository;
/**
* @var ColorHelper
*/
private $colorHelper;
/**
* @param CalculoRepository $calculoRepository
* @param ColorHelper $colorHelper
*/
public function __construct(CalculoRepository $calculoRepository, IndicadorRepository $indicadorRepository, RastreabilidadeRepository $rastreabilidadeRepository, ColorHelper $colorHelper)
{
$this->calculoRepository = $calculoRepository;
$this->indicadorRepository = $indicadorRepository;
$this->rastreabilidadeRepository = $rastreabilidadeRepository;
$this->colorHelper = $colorHelper;
}
/**
* @param Request $request
* @return Response
*/
public function index(Request $request): Response
{
$id_busca = $request->query->get('id_busca', null);
$id_avaliado = $request->query->get('id_filtro', null);
$this->getSession()->set('id_busca', $id_busca);
$gestor_permissoes = $this->getSession()->get('gestor_permissoes');
//Monta as strings de busca da query a ser executada
$filtro = Dimensao::defineFiltro((array) $id_busca, $id_avaliado);
$dados = $this->calculoRepository->getIndicadoresContagemPorDesempenho($this->getPrograma(), $this->getPeriodo(), $filtro, $gestor_permissoes['where']);
$dados = $this->processo($dados);
return $this->render('evs-distribuicao-indicadores.html.twig', [
'dados' => $dados
,'id_busca' => $id_busca
]);
}
/**
* @Route("/reload", name="distribuicao_indicadores_reload")
*
* @param Request $request
* @return Response
*/
public function reload(Request $request): Response
{
$id_busca = $request->query->get('id_busca', null);
$this->getSession()->set('id_busca', $id_busca);
$id_filtro = $request->query->get('id_filtro', null);
$dimensao = $request->query->get('dimensao', null);
$gestor_permissoes = $this->getSession()->get('gestor_permissoes');
$filtro = Dimensao::atualizaFiltro($dimensao, $id_filtro, $id_busca);
$dados = $this->calculoRepository->getIndicadoresContagemPorDesempenho($this->getPrograma(), $this->getPeriodo(), $filtro, $gestor_permissoes['where']);
$dados = $this->processo($dados);
return $this->render('evs-distribuicao-indicadores.html.twig', [
'dados' => $dados,
]);
}
/**
* @Route("/detalhes-grafico/{id_indicador}/{performance}"
* ,requirements={"id_indicador"="\d+"}
* ,name="distribuicao_indicadores_detalhes_grafico"
* )
* @param integer $id_indicador
* @param float $performance
* @return Response
*/
public function detalhesGraficoDistribuicao(int $id_indicador, float $performance) :Response
{
$dimensao = $this->getSession()->get('dimensao');
$id_busca = $dimensao->getIdBusca();
$id_avaliado = $dimensao->getIdFiltro();
$filtro = Dimensao::defineFiltro((array) $id_busca, $id_avaliado);
unset($dimensao);
$indicador = $this->indicadorRepository->find($id_indicador);
$periodoSessao = $this->getSession()->get('visao_gestor_periodo');
$from = $periodoSessao['from']['ano'] . $periodoSessao['from']['periodo'];
$to = $periodoSessao['to']['ano'] . $periodoSessao['to']['periodo'];
$periodos = [];
while ( $from <= $to ) {
$periodos[] = intval($from);
if (substr($from, -2) == 12 ) {
$from = $from + 89;
} else {
$from++;
}
}
$hasNovoCalculo = $this->calculoRepository->checkIfHasBancoNovoCalculo($id_indicador);
if ( $hasNovoCalculo ) {
$dados = $this->calculoRepository->getDetalhesDesempenhoIndicadorNovoCalculoFaixa(
$id_indicador, $periodoSessao, $filtro, $this->getPrograma(), $performance
);
foreach ($dados AS $dado) {
if ( !isset($dadosNovos[$dado['id_avaliado']]) ) {
$dadosNovos[$dado['id_avaliado']] = [
'id_avaliado' => $dado['id_avaliado'],
'nome_avaliado' => $dado['nome_avaliado'],
'id_indicador' => $dado['id_indicador'],
'indicador' => $dado['indicador'],
'unidade_indicador' => $dado['unidade_indicador'],
'avaliado_media_performance' => $dado['avaliado_media_performance'],
'nome_grupo' => $dado['nome_grupo'],
'performance_0' => $dado['performance_0'],
'performance_1' => $dado['performance_1'],
'resultado' => [],
'performances' => $dado['performances']
];
}
$dadosNovos[$dado['id_avaliado']]['resultado'][] = $dado['resultado'];
}
if ( !empty($dadosNovos) ) {
foreach ($dadosNovos AS &$value) {
$resultadoAvaliados = json_decode($value['resultado'][array_key_last($value['resultado'])], true);
if ( array_values($resultadoAvaliados)[0]['performance'] === null ) {
unset($value['resultado'][array_key_last($value['resultado'])]);
}
$resultadoArray = isset($value['resultado'][0]) ? json_decode($value['resultado'][0], true) : [];
$periodosResultado = !empty($resultadoAvaliados) ? array_keys($resultadoAvaliados + $resultadoArray) : array_keys($resultadoArray);
foreach ( $value['resultado'] AS &$valor) {
$valor = json_decode($valor, true);
if (array_values($resultadoAvaliados)[0]['performance'] === null ) {
$valor = $resultadoAvaliados + $valor;
}
$periodosResultado = array_keys($valor) + $periodosResultado;
if (array_diff($periodos, $periodosResultado)) {
foreach (array_unique(array_diff($periodos, $periodosResultado)) AS $periodoFaltando) {
if ( array_values($resultadoAvaliados)[0]['risco'] === null ) {
$valor[$periodoFaltando] = array_values($resultadoAvaliados)[0];
} else {
$valor[$periodoFaltando] = [
'risco' => null,
'valor' => null,
'numerador' => null,
'denominador' => null,
'performance' => null,
'performance_risco' => null,
];
}
}
}
ksort($valor);
$valor = json_encode($valor);
}
$value['performances'] = json_decode($value['performances'], true);
foreach ($periodos AS $periodoKey) {
if ( !isset($value['performances'][$periodoKey]) ) {
$value['performances'][$periodoKey] = null;
}
}
ksort($value['performances']);
$value['performances'] = json_encode($value['performances']);
}
$dados = array_values($dadosNovos);
}
} else {
$dados = $this->calculoRepository->getDetalhesDesempenhoIndicador(
$id_indicador, $periodoSessao, $filtro, $this->getPrograma(), $performance
);
}
return $this->render('detalhe-evs-distribuicao-indicadores.html.twig', [
'dados' => $dados
,'periodos' => array_values($periodos)
,'faixa' => $performance
,'indicador' => $indicador
]);
}
/**
* @param ResultStatement $dados
* @return array
*/
public function processo(ResultStatement $dados): array
{
$retorno = [];
foreach ($dados as $dominio) {
$retorno[$dominio['nome_dominio']] = [];
foreach (json_decode($dominio['indicadores'], true) as $dominio_key => $indicador) {
$retorno[$dominio['nome_dominio']]['categorias'][$dominio_key] = [
'value' => $indicador['nome_indicador'],
'url' => $this->generateUrl('distribuicao_indicadores_detalhes_grafico', [
'id_indicador' => $indicador['id_indicador']
,'performance' => 999
])
];
foreach ($indicador['performance'] as $key_performance => $performance) {
if (!is_null($performance)) {
$retorno[$dominio['nome_dominio']]['categorias'][$dominio_key]['vazio'] = false;
$retorno[$dominio['nome_dominio']]['series'][strval($performance)]['name'] = $performance;
$retorno[$dominio['nome_dominio']]['series'][strval($performance)]['data'][(int) $dominio_key] = [
'y' => $indicador['contagem'][$key_performance],
'color' => $this->colorHelper->numberToColorHsl($performance ?? 0),
'valor_total' => $indicador['total_indicador'],
'url' => $this->generateUrl('distribuicao_indicadores_detalhes_grafico', [
'id_indicador' => $indicador['id_indicador']
,'performance' => $performance
])
];
} else {
//O 'nome' da posição no gráfico é 101 para que a faixa ND fique sempre à direita
$retorno[$dominio['nome_dominio']]['series'][strval($performance)]['name'] = 101;
//Por conta da rota do gráfico receber apenas números, foi definido que -1 seria o número da faixa ND
$retorno[$dominio['nome_dominio']]['series'][strval($performance)]['data'][(int) $dominio_key] = [
'y' => $indicador['contagem'][$key_performance],
'color' => '#D1D1D1',
'valor_total' => $indicador['total_indicador'],
'url' => $this->generateUrl('distribuicao_indicadores_detalhes_grafico', [
'id_indicador' => $indicador['id_indicador']
,'performance' => -1
])
];
$retorno[$dominio['nome_dominio']]['categorias'][$dominio_key]['vazio'] = isset($retorno[$dominio['nome_dominio']]['categorias'][$dominio_key]['vazio']) ? false : true;
}
$retorno[$dominio['nome_dominio']]['series'][strval($performance)]['data'] = $this->organizaArray($dominio_key, $retorno[$dominio['nome_dominio']]['series'][strval($performance)]['data']);
}
}
ksort($retorno[$dominio['nome_dominio']]['series']);
rsort($retorno[$dominio['nome_dominio']]['series']);
$retorno[$dominio['nome_dominio']]['series'] = json_encode($retorno[$dominio['nome_dominio']]['series']);
$retorno[$dominio['nome_dominio']]['categorias'] = json_encode($retorno[$dominio['nome_dominio']]['categorias']);
}
return $retorno ?? [];
}
/**
* Trata o array para funcionar no highcharts sem erros de informações em linhas diferentes
* este metodo é necessario para que o highcharts tenha as posições zeradas quando existirem 2 linhas para o mesmo dominio.
* Aqui ele pegará o array e irá preenxelo com valores zero para as posições onde existem informações, assim nunca haverá um array com apenas a posição 1,
* pois essa função criará a posição de acordo com a chave passada.
*
* @author Guilhermer Arduino <guilherme.barlatti@2im.com.br>
*
* @param integer $key
* @param array $array
* @return array
*/
public function organizaArray(int $key, array $array): array
{
$cria_array = range(0, $key);
foreach ($cria_array as $chave) {
if (!array_key_exists($chave, $array)) {
$array[$chave] =
[
'y' => 0,
];
}
}
ksort($array);
return $array;
}
/**
* @Route("/detalhes-grafico-rastreabilidade"
* ,name="distribuicao_indicadores_detalhes_rastreabilidade"
* )
*
* @param integer $id_indicador
* @param integer $id_avaliado
* @param integer $periodo
*
* @return Response
*/
public function detalhesGraficoDistribuicaoRasteabilidade(Request $request) :Response
{
$dimensao = $this->getSession()->get('dimensao');
$id_busca = $dimensao->getIdBusca();
$id_avaliado = $dimensao->getIdFiltro();
$filtro = Dimensao::defineFiltro((array) $id_busca, $id_avaliado);
unset($dimensao);
$id_indicador = $request->query->get('id_indicador');
$id_avaliado = $request->query->get('id_avaliado');
$periodo = $request->query->get('periodo');
$indicador = $this->indicadorRepository->find($id_indicador);
if($indicador->getIdIndicadorTipo() == 3) {
$dados = $this->rastreabilidadeRepository->getRastrabilidadeVariavelByIndicador(
$this->getPrograma()['where']
, $periodo
, null
, $id_avaliado
, $id_indicador
);
$rastreabilidades = [];
foreach($dados AS $k => $d) {
$rastreabilidades[$d['id_ajuste_risco']][$d['tipo']] = $dados[$k];
}
return $this->render('detalhe-evs-distribuicao-indicadores-rastreabilidade-ar.html.twig', [
'nome_indicador' => $dados[0]['titulo'] ?? ''
, 'id_indicador' => $dados[0]['id_indicador'] ?? ''
, 'periodo' => DateHelper::toString($periodo)
, 'rastreabilidades' => $rastreabilidades ?? []
]);
} elseif($indicador->getIdIndicadorTipo() == 2) {
$dados = $this->calculoRepository->getDetalhesDesempenhoIndicadorRastreabilidadeDrg(
$id_indicador, $periodo, $filtro, $this->getPrograma(), $id_avaliado
);
return $this->render('detalhe-evs-distribuicao-indicadores-rastreabilidade-drg.html.twig', [
'nome_indicador' => $indicador->getTitulo() ?? ''
, 'id_indicador' => $indicador->getIdIndicador() ?? ''
, 'periodo' => DateHelper::toString($periodo)
, 'rastreabilidades' => $dados ?? []
]);
} else {
$dados = $this->calculoRepository->getDetalhesDesempenhoIndicadorRastreabilidade(
$id_indicador, $periodo, $filtro, $this->getPrograma(), $id_avaliado
);
}
if(!$dados) {
$dados = $this->calculoRepository->getCalculo(
$id_indicador, $periodo, $filtro, $this->getPrograma(), $id_avaliado
);
$banda = json_decode($dados['dados'], TRUE);
$periodo = json_decode($dados['periodo'], TRUE);
$ficha_tecnica = json_decode($dados['ficha_tecnica'], TRUE);
if(isset($banda['banda']['tipo']) && $banda['banda']['tipo'] == 'ND') {
return $this->render('detalhe-evs-distribuicao-indicadores-rastreabilidade-nd.html.twig', [
'nome_indicador' => $dados['nome_indicador']
, 'id_indicador' => $dados['id_indicador']
, 'ficha_tecnica' => $ficha_tecnica
, 'periodo' => DateHelper::toString($periodo['ano'].$periodo['periodo'])
, 'texto' => $banda['resultado']['txt']
]);
}
}
$numerador = $denominador = [];
$cabecalho = json_decode($dados['cabecalho'], TRUE);
$numerador = [
'cabecalho' => $cabecalho['numerador']
, 'dados' => json_decode($dados['numerador'], TRUE)
];
if(isset($cabecalho['denominador'])) {
$denominador = [
'cabecalho' => $cabecalho['denominador']
, 'dados' => json_decode($dados['denominador'], TRUE)
];
}
$periodo = json_decode($dados['periodo'], TRUE);
$ficha_tecnica = json_decode($dados['ficha_tecnica'], TRUE);
return $this->render('detalhe-evs-distribuicao-indicadores-rastreabilidade.html.twig', [
'nome_indicador' => $dados['titulo']
, 'id_indicador' => $dados['id_indicador']
, 'periodo' => DateHelper::toString($periodo['ano'].$periodo['periodo'])
, 'ficha_tecnica' => $ficha_tecnica
, 'numerador' => $numerador
, 'denominador' => $denominador
]);
}
}