<?php
namespace App\Controller;
use App\Entity\Solicitacao;
use App\Repository\SolicitacaoRepository;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/aprovador')]
class AprovadorController extends AbstractController
{
/**
* Normaliza o campo de filtro antigo "u.numeroLancamento" para "s.numeroLancamento".
* Se detectar o valor antigo na query, faz um redirect 302 para a mesma rota com o valor corrigido.
*/
private function normalizeFilterField(Request $request, string $routeName, array $routeParams = []): ?Response
{
$filterField = $request->query->get('filterField');
if ($filterField === 'u.numeroLancamento') {
$params = $request->query->all();
$params['filterField'] = 's.numeroLancamento';
// Mantém a navegação/ordenacão atuais mas troca apenas o campo
return $this->redirectToRoute($routeName, array_merge($routeParams, $params));
}
return null;
}
#[Route(
'/empresa/{empresaId}/{status}',
name: 'app_aprovador_empresa_status',
methods: ['GET'],
defaults: ['status' => 'pendentes'],
requirements: ['status' => 'pendentes|pre-aprovados|aprovados|todos']
)]
public function empresaPorStatus(
SolicitacaoRepository $solicitacaoRepository,
Request $request,
PaginatorInterface $paginator,
int $empresaId,
string $status
): Response {
$user = $this->getUser();
// Acesso: SUPER vê tudo; senão precisa pertencer à empresa
$hasAccess = $this->isGranted('ROLE_SUPER');
if (!$hasAccess) {
foreach ($user->getEmpresas() as $empresa) {
if ($empresa->getId() === $empresaId) {
$hasAccess = true;
break;
}
}
}
if (!$hasAccess) {
throw $this->createAccessDeniedException('Você não tem permissão para acessar as solicitações desta empresa.');
}
// Normaliza filtro legado e limpa filtro vazio (evita lista zerada)
$filterField = $request->query->get('filterField');
$filterValue = $request->query->get('filterValue');
if ($filterField === 'u.numeroLancamento') {
$params = $request->query->all();
$params['filterField'] = 's.numeroLancamento';
return $this->redirectToRoute('app_aprovador_empresa_status', array_merge([
'empresaId' => $empresaId,
'status' => $status,
], $params));
}
if ($filterField && is_string($filterValue) && trim($filterValue) === '') {
$params = $request->query->all();
unset($params['filterField'], $params['filterValue']);
return $this->redirectToRoute('app_aprovador_empresa_status', array_merge([
'empresaId' => $empresaId,
'status' => $status,
], $params));
}
// Mapa de status base
$statusMap = [
'pendentes' => Solicitacao::STATUS_PENDENTE, // será ajustado para SUPER
'pre-aprovados' => Solicitacao::STATUS_APROVADOR_OK,
'aprovados' => Solicitacao::STATUS_ADMINISTRADOR_OK,
'todos' => null, // sem filtro
];
// Fallback padrão coerente
$statusCode = array_key_exists($status, $statusMap)
? $statusMap[$status]
: Solicitacao::STATUS_PENDENTE;
// Ajuste semântico: para SUPER, "pendentes" = pré-aprovados do aprovador
if ($status === 'pendentes' && $this->isGranted('ROLE_SUPER')) {
$statusCode = Solicitacao::STATUS_APROVADOR_OK;
}
// Monta QB (se $statusCode for null, não aplica filtro de status)
$qb = $solicitacaoRepository->qbByEmpresaAndStatus($empresaId, $statusCode);
$pagination = $paginator->paginate(
$qb,
$request->query->getInt('page', 1),
10,
[
'defaultSortFieldName' => 's.updatedAt',
'defaultSortDirection' => 'desc',
'sortFieldAllowList' => ['s.titulo', 's.valor', 's.numeroLancamento', 's.vencimento', 's.status', 's.updatedAt'],
'filterFieldAllowList' => ['s.numeroLancamento'],
]
);
return $this->render('aprovador/index.html.twig', [
'solicitacoes' => $pagination,
'nav_active' => ucfirst($status),
'empresaId' => $empresaId,
'subEmpresaId' => null,
]);
}
#[Route(
'/subempresa/{subEmpresaId}/{status}',
name: 'app_aprovador_subempresa_status',
methods: ['GET'],
defaults: ['status' => 'pendentes'],
requirements: ['status' => 'pendentes|pre-aprovados|aprovados|todos']
)]
public function subEmpresaPorStatus(
SolicitacaoRepository $solicitacaoRepository,
Request $request,
PaginatorInterface $paginator,
int $subEmpresaId,
string $status
): Response {
$user = $this->getUser();
$hasAccess = false;
foreach ($user->getSubEmpresas() as $subEmpresa) {
if ($subEmpresa->getId() === $subEmpresaId) {
$hasAccess = true;
break;
}
}
if (!$hasAccess) {
throw $this->createAccessDeniedException('Você não tem permissão para acessar as solicitações desta empresa.');
}
// Normaliza filtro legado também nesta rota
if ($resp = $this->normalizeFilterField($request, 'app_aprovador_subempresa_status', [
'subEmpresaId' => $subEmpresaId,
'status' => $status,
])) {
return $resp;
}
$statusMap = [
'pendentes' => Solicitacao::STATUS_PENDENTE,
'pre-aprovados' => Solicitacao::STATUS_APROVADOR_OK,
'aprovados' => Solicitacao::STATUS_ADMINISTRADOR_OK,
'todos' => Solicitacao::STATUS_TODOS
];
$statusCode = $statusMap[$status] ?? Solicitacao::STATUS_PENDENTE;
$qb = $statusCode === Solicitacao::STATUS_TODOS
? $solicitacaoRepository->qbBySubEmpresa($subEmpresaId)
: $solicitacaoRepository->qbBySubEmpresaAndStatus($subEmpresaId, $statusCode);
$pagination = $paginator->paginate(
$qb,
$request->query->getInt('page', 1),
10,
[
'defaultSortFieldName' => 's.updatedAt',
'defaultSortDirection' => 'desc',
'sortFieldAllowList' => ['s.titulo', 's.valor', 's.numeroLancamento', 's.vencimento', 's.status', 's.updatedAt'],
'filterFieldAllowList' => ['s.numeroLancamento'],
]
);
return $this->render('aprovador/index.html.twig', [
'solicitacoes' => $pagination,
'nav_active' => ucfirst($status),
'subEmpresaId' => $subEmpresaId,
]);
}
}