<?php
namespace App\Controller\Visao\Gestor;
use App\Controller\Componentes\PeriodoController;
use App\Controller\Customs\Custom2IMController;
use App\Entity\Cliente\Dimensao;
use App\Repository\Cliente\Dados\CalculoRepository;
use App\Repository\Cliente\Dados\EvsRepository;
use App\Repository\Cliente\Dados\ScorecardRepository;
use App\Repository\Cliente\Fornecidos\DadosEnviadosRepository;
use App\Repository\Cliente\Fornecidos\SolicitacaoRepository;
use App\Repository\Cliente\Modelagem\AvaliadoRepository;
use App\Repository\Cliente\Modelagem\ProgramaRepository;
use App\Repository\Cliente\Privilegios\AvaliacaoRepository;
use App\Repository\Painel\VisaoRepository;
use App\Service\S3Service;
use Exception;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\RouterInterface;
/**
* @Route("/visao-gestor")
*/
class GestorController extends Custom2IMController
{
const TEMPLATEBASE = 'visao/gestor/';
/**
* @var array
*/
public $rotas = ['visa_gestor_dashboard', 'relatorio_dashboard'];
/**
* @var string
*/
protected $visao = 'gestor';
/**
* @var ProgramaRepository
*/
private $programaRepository;
/**
* @var VisaoRepository
*/
private $visaoRepository;
/**
* @var EvsRepository
*/
private $evsRepository;
/**
* @var RouterInterface
*/
private $router;
/**
* @var PeriodoController
*/
private $servicePeriodoController;
/**
* @var CalculoRepository
*/
private $calculoRepository;
/**
* @var AvaliadoRepository
*/
private $avaliadoRepository;
/**
* @var DadosEnviadosRepository
*/
private $dadosEnviadosRepo;
/**
* @var SolicitacaoRepository
*/
private $solicitacaoRepository;
/**
* @var S3Service
*/
private $s3;
/**
* @param ProgramaRepository $programaRepository
* @param VisaoRepository $visaoRepository
* @param EvsRepository $evsRepository
* @param RouterInterface $router
*/
public function __construct(
ProgramaRepository $programaRepository
,VisaoRepository $visaoRepository
,EvsRepository $evsRepository
,RouterInterface $router
,PeriodoController $servicePeriodoController
,RequestStack $requestStack
,CalculoRepository $calculoRepository
,AvaliadoRepository $avaliadoRepository
,DadosEnviadosRepository $dadosEnviadosRepository
,SolicitacaoRepository $solicitacaoRepository
,S3Service $s3Service
) {
$this->programaRepository = $programaRepository;
$this->visaoRepository = $visaoRepository;
$this->evsRepository = $evsRepository;
$this->router = $router;
$this->servicePeriodoController = $servicePeriodoController;
$this->calculoRepository = $calculoRepository;
$this->avaliadoRepository = $avaliadoRepository;
$this->dadosEnviadosRepo = $dadosEnviadosRepository;
$this->solicitacaoRepository = $solicitacaoRepository;
$this->s3 = $s3Service;
// mantem a sessao de periodo para visao do gestor
// existe um conflito de sessao.periodo em todas as visoes
// esta condicao mantem para visao_gestor
$sess = $requestStack->getSession();
if ( $sess->has('modelagem') AND (NULL !== $sess->get('periodo')) ) {
// see PeriodoController::processa
$requestStack->getSession()->set('periodo', $requestStack->getSession()->get('visao_gestor_periodo'));
}
// remove a chave da sessao do periodo
if ( NULL === $sess->get('periodo') ) {
$sess->remove('periodo');
}
unset($sess);
}
/**
* Render Controller in templates/visao/gestor/base.html.twig
* @param Request $request
* @return Response
*/
public function defineDimensao(Request $request): Response
{
$dimensao = $request->query->get('dimensao');
$id_busca = $request->query->get('id_busca', null);
$id_avaliado = $request->query->get('id_filtro', null);
$dimensao = (new Dimensao())
->setDimensao($dimensao)
->setIdBusca($id_busca)
->setIdFiltro($id_avaliado)
->setPrograma($this->getPrograma())
->setPeriodo($this->getPeriodo());
// persiste o objeto da Dimensao na sessao
$this->getSession()->set('dimensao', $dimensao);
return $this->render($dimensao->getTemplate(), [
'dimensao' => $dimensao,
]);
}
/**
* @Route("/dashboard/{dimensao}", name="visao_gestor_dashboard")
*
* @param Request $request
* @param string|null $dimensao
* @return Response
*/
public function index(Request $request, string $dimensao = null) :Response
{
$this->setarSessoesVisao('Gestor', true, false, $this->hasPeriodo() ? '' : 'no-periodo', 'visao_gestor_dashboard');
$gestor_permissoes = $this->getSession()->get('gestor_permissoes');
$visaoObj = $this->visaoRepository->findOneBy(['slug' => $this->visao]);
$id_busca = $request->query->get('id_busca', null);
$id_avaliado = $request->query->get('id_filtro', null);
$valida = $this->testaPermissoes(
($visaoObj ? $visaoObj->getIdVisao() : 0),
$this->getUser()->getPerfil()->getRota_default(),
$this->router,
$this->visaoRepository
);
if ($valida) {
return $valida;
}
if ($this->hasModelagem() && !$this->getModelagem()->getPrograma()->getEvs() && $this->getPeriodo()) {
return $this->redirectToRoute('gps_visao_gestor_dashboard');
}
if ( $dimensao && !$id_busca ) {
return $this->redirectToRoute('visao_gestor_dashboard');
}
$especialidade_selecionada = null;
if ( Dimensao::POR_ESPECIALIDADE === $dimensao ) {
$especialidade_selecionada = $this->evsRepository->buscarPerformanceDaEspecialidade($this->getPrograma(), $this->getPeriodo(), $id_busca, $gestor_permissoes['where']);
$this->getSession()->set('especialidade', $especialidade_selecionada);
}
$programas = $this->programaRepository->findAll();
$filtro = Dimensao::defineFiltro((array) $id_busca, $id_avaliado);
//Informações de qtd de grupos, avaliados e indicadores com performance e os seus totais
$informacoesAlertas = null;
$abaixoNotaCorte = null;
$qtdAcessos = 0;
if (!is_null($this->getPeriodo())) {
$filtroSemAvaliado = Dimensao::defineFiltro((array) $id_busca);
$informacoesAlertas = [
'qtds' => $this->calculoRepository->findQtdsAlertasGestor($this->getPeriodo(), $filtro, $this->getPrograma(), $gestor_permissoes['where']),
'totais' => $this->calculoRepository->findTotaisAlertasGestor($this->getPeriodo(), $filtro, $this->getPrograma())
];
$abaixoNotaCorte = [
'avaliados' => $this->calculoRepository->findQtdAvaliadosAbaixoNotaCorte($this->getPeriodo(), $filtro, $this->getPrograma(), $gestor_permissoes['where']),
'grupos' => $this->calculoRepository->findQtdGruposAbaixoNotaCorte($this->getPeriodo(), $filtroSemAvaliado, $this->getPrograma(), $gestor_permissoes['where'])
];
$qtdAcessos = $this->avaliadoRepository->findCountAvaliadosWithAcesso($this->getPeriodo(), $filtro, $this->getPrograma());
}
$avaliado = null;
if ( null !== $id_avaliado ) {
$avaliado = $this->avaliadoRepository->find($id_avaliado);
}
$this->getSession()->remove('telas');
return $this->render('base.html.twig', [
'especialidade_selecionada' => $especialidade_selecionada,
'programas' => $programas,
'dimensao' => $dimensao,
'id_busca' => $id_busca,
'id_filtro' => $request->query->get('id_filtro', null), // para avaliado
'alertas' => $informacoesAlertas,
'abaixoNotaCorte' => $abaixoNotaCorte,
'avaliado' => $avaliado,
'qtdAcessos' => $qtdAcessos
]);
}
/**
* @isGranted("ROLE_GESTOR")
* @Route("/redirect/avaliado/{id}", name="redirect_avaliado_dashboard")
*
* @param Request $request
* @param EvsRepository $evs
* @param RouterInterface $router
* @param integer $id ID avaliado
* @return RedirectResponse
*/
public function redirectAvaliadoDashboard(Request $request, EvsRepository $evs, RouterInterface $router,int $id) :RedirectResponse
{
// dados do ultimo mes do avaliado
// [id_avaliado,id_programa,id_modelagem,id_grupo]
$ano = $this->getPeriodo()['to']['ano'];
$mes = $this->getPeriodo()['to']['periodo'];
$periodo = (int) join('',[$ano,$mes]);
$avaliado = current($evs->avaliadoMesesComAvaliacao([
'id_avaliado' => $id
,'id_programa' => $this->getPrograma()['programa']['id_programa']
,'id_modelagem' => $this->getPrograma()['modelagem']
,'id_grupo' => $this->getSession()->get('id_busca')
], $ano, $periodo));
// session avaliado setter
$this->getSession()->set('avaliado', $avaliado + ['http_referer' => 'visao_gestor']);
// para periodo
$ultimoPeriodoProducao = $avaliado['periodo'];
$ano = substr($ultimoPeriodoProducao,0,4);
$mes = substr($ultimoPeriodoProducao,-2);
// as service
// periodo_multiplo para periodo_unico
// simula select do avaliado
$this->servicePeriodoController->processa($request, [
'from' => join('|',['Mensal',$ano, $mes])
,'to' => join('|',['Mensal',$ano, $mes])
,'referer' => 'avaliado'
]);
return $this->redirect($router->generate('visao_avaliado_dashboard'));
}
/**
* @Route("/nota-corte/avaliado", name="visao_gestor_nota_corte_avaliado")
*/
public function detalhesAvaliado(Request $request, EvsRepository $evsRepository): Response
{
$id_busca = $this->getSession()->get('id_busca');
$id_avaliado = $this->getSession()->get('dimensao')->getIdFiltro();
$gestor_permissoes = $this->getSession()->get('gestor_permissoes');
$filtro = Dimensao::defineFiltro((array) $id_busca, $id_avaliado);
$avaliados = $evsRepository->avaliadosNotaCorte($this->getPrograma(), $this->getPeriodo(), $filtro, $gestor_permissoes['where']);
return $this->render('modal-nota-corte-avaliado.html.twig', [
'avaliados' => $avaliados
]);
}
/**
* @Route("/nota-corte/grupo", name="visao_gestor_nota_corte_grupo")
*/
public function detalhesGrupo(Request $request, EvsRepository $evsRepository): Response
{
$id_busca = $this->getSession()->get('id_busca');
$gestor_permissoes = $this->getSession()->get('gestor_permissoes');
$filtro = Dimensao::defineFiltro((array) $id_busca);
$grupos = $evsRepository->gruposNotaCorte($this->getPrograma(), $this->getPeriodo(), $filtro, $gestor_permissoes['where']);
return $this->render('modal-nota-corte-grupo.html.twig',[
'grupos' => $grupos
]);
}
/**
* listagem dos avaliados por especialidade
* @Route("/avaliados/{id_especialidade}", name="visao_gestor_avaliados_especialidade")
*/
public function avaliadosPorEspecialidade(Request $request, int $id_especialidade, ScorecardRepository $scorecardRepository): Response
{
$modelagem = $this->getPrograma()['modelagem'] ?? false;
$periodo = $this->getPeriodo() ?
(int) ($this->getPeriodo()['to']['ano'] . str_pad($this->getPeriodo()['to']['periodo'], 2, '0', STR_PAD_LEFT)) :
false;
$avaliados = $scorecardRepository->findAvaliadosPorEspecialidade($id_especialidade, $modelagem, $periodo);
return $this->render('modal-avaliados-especialidade.html.twig', [
'avaliados' => $avaliados,
'id_especialidade' => $id_especialidade
]);
}
/**
* @Route("/acesso", name="visao_gestor_acesso_avaliados")
*/
public function acessoAvaliados(Request $request): Response
{
$id_busca = $this->getSession()->get('id_busca');
$id_avaliado = $this->getSession()->get('dimensao')->getIdFiltro();
$gestor_permissoes = $this->getSession()->get('gestor_permissoes');
$filtro = Dimensao::defineFiltro((array) $id_busca, $id_avaliado);
$avaliados = $this->avaliadoRepository->findAvaliadosWithAcesso($this->getPeriodo(), $filtro, $this->getPrograma(), $gestor_permissoes['where']);
return $this->render('modal-acesso-avaliados.html.twig',[
'avaliados' => $avaliados
]);
}
/**
* @Route("/acesso/{id_avaliado}", name="visao_gestor_acesso_avaliado_detalhe")
*/
public function detalhesAcessoAvaliado(Request $request, int $id_avaliado): Response
{
$acessos = $this->avaliadoRepository->findDetalhesAvaliadoAcesso($id_avaliado, $this->getPeriodo());
return $this->render('modal-acesso-avaliado-detalhe.html.twig',[
'acessos' => $acessos
]);
}
/**
* @Route("/decil/avaliados", name="visao_gestor_decil_avaliados")
*/
public function decilAvaliados(Request $request, EvsRepository $evsRepository)
{
$id_busca = $this->getSession()->get('id_busca');
$id_avaliado = $this->getSession()->get('dimensao')->getIdFiltro();
$filtro = Dimensao::defineFiltro((array) $id_busca, $id_avaliado);
$decil = $request->query->get('decil');
$avaliados = $evsRepository->avaliadosDecil($this->getPrograma(), $this->getPeriodo(), $filtro, $decil);
return $this->render('modal-decil-avaliados.html.twig',[
'decil' => $decil,
'avaliados' => $avaliados
]);
}
/**
* @Route("/privilegios/relatorio", name="visao_gestor_relatorio_privilegios")
*/
public function privilegiosRelatorio(AvaliacaoRepository $avaliacaoRepository): Response
{
$id_busca = $this->getSession()->get('id_busca', null);
$id_avaliado = $this->getSession()->get('dimensao')->getIdFiltro() ?? null;
$privilegios = $avaliacaoRepository->findAllAvaliadosPrivilegios($this->getPrograma(), $id_busca, $id_avaliado);
return $this->render('privilegios-relatorio.html.twig',[
'privilegios' => $privilegios
]);
}
/**
* @Route("/documentos-recebidos", name="visao_gestor_documentos_recebidos")
*/
public function documentosRecebidos(Request $request, PaginatorInterface $paginatorInterface)
{
$gestor_permissoes = $this->getSession()->get('gestor_permissoes');
$currentPage = (int) $request->query->get('page',1);
$paginator = $paginatorInterface->paginate([],$currentPage);
$limit = $paginator->getItemNumberPerPage();
$offset = ($currentPage - 1) * $limit;
$busca = filter_var($request->query->get('busca'), FILTER_SANITIZE_SPECIAL_CHARS);
preg_match("/AND id_avaliado IN\((.*?)\)/", $gestor_permissoes['where'], $matches);
$resultDadosEnviados = $this->dadosEnviadosRepo->findArquivosEnviados(
$limit
,$offset
,$busca
,$request->query->get('sort')
,$request->query->get('direction')
, NULL
,$matches[0] ?? NULL //AND id_avaliado IN(....)
);
$paginator->setTotalItemCount($resultDadosEnviados[0]['num_rows'] ?? 0);
$paginator->setItems($resultDadosEnviados);
return $this->render('componentes/solicitacao-documentos/gestor-equipe-recebidos.html.twig', [
'pagination' => $paginator
]);
}
/**
* @Route("/aprovar-documento/{id_arquivo}/{aprovar}", name="visao_gestor_aprovar_documento")
*/
public function aprovarDocumento(Request $request, int $id_arquivo, string $aprovar)
{
if ( $aprovar === "true" ) {
$aprovar = TRUE;
} else if ( $aprovar === "false") {
$aprovar = FALSE;
}
$dadosEnviadosObject = $this->dadosEnviadosRepo->findOneBy(['idArquivo' => $id_arquivo]);
$dadosEnviadosObject->setAprovado($aprovar === TRUE ?: FALSE);
try {
$this->dadosEnviadosRepo->save($dadosEnviadosObject);
$this->addFlash("success", "Salvo com sucesso!");
} catch (Exception $ex) {
$this->addFlash("error", "Ocorreu um erro ao salvar!");
}
return $this->redirect($request->headers->get('referer'));
}
/**
* @Route("/visualizar-documento/{id}", name="visualizar_documento")
*/
public function documento(Request $request, int $id)
{
$documento = $this->dadosEnviadosRepo->getArquivoById($id);
return $this->render('componentes/solicitacao-documentos/modal-documento.html.twig', [
'documento'=>$documento
]);
}
/**
* @Route("/download-documento/{id_arquivo}", name="visao_gestor_documentos_download")
*/
public function download(Request $request, int $id_arquivo)
{
$client = $request->getSession()->get('cliente_connection');
$arquivo = $this->dadosEnviadosRepo->findOneBy(['idArquivo' => $id_arquivo]);
$fileName = substr($arquivo->getFilePath(), strrpos($arquivo->getFilePath(), '/') + 1);
$solicitacao = $this->solicitacaoRepository->findOneBy(['idSolicitacao' => $arquivo->getIdSolicitacao()]);
$pathToFile = $client['dbname'].'/'.$solicitacao->getPastaSlug().'/'.$fileName;
$fileUrl = $this->s3->presignedGetObjectRequest($_ENV['AWS_S3_BUCKET'], $pathToFile);
if (!$fileUrl) {
$this->addFlash(
'error',
'Arquivo não encontrado.'
);
return $this->redirect($request->headers->get('referer'));
}
$stream = fopen($fileUrl, 'r');
return new StreamedResponse(function () use ($stream) {
fpassthru($stream);
flush();
}, 200, [
'Content-Transfer-Encoding', 'binary',
// 'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename=' . $fileName,
]);
}
}