suivi/src/Controller/ExpenseReportAdminController.php
2022-12-19 18:35:10 +01:00

443 lines
16 KiB
PHP

<?php
namespace App\Controller;
use App\Core\Controller\Admin\Crud\CrudController;
use App\Core\Crud\CrudConfiguration;
use App\Core\Crud\Field;
use App\Core\Entity\EntityInterface;
use App\Core\Form\FileUploadHandler;
use App\Core\Manager\EntityManager;
use App\Entity\ExpenseReport as Entity;
use App\Event\EntityManagerEvent;
use App\Factory\ExpenseReportFactory as Factory;
use App\Form\ExpenseReportType as Type;
use App\Repository\ExpenseReportRepositoryQuery as RepositoryQuery;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;
class ExpenseReportAdminController extends CrudController
{
protected FileUploadHandler $fileUpload;
protected Filesystem $fs;
public function __construct(FileUploadHandler $fileUpload, Filesystem $fs)
{
$this->fileUpload = $fileUpload;
$this->fs = $fs;
}
#[Route(path: '/admin/expense_report/{page}', name: 'admin_expense_report_index', methods: ['GET'], requirements: ['page' => '\d+'])]
public function index(RepositoryQuery $query, Request $request, Session $session, int $page = 1): Response
{
if (!$this->isGranted('ROLE_TREASURER')) {
$query->filterByUser($this->getUser());
}
return $this->doIndex($page, $query, $request, $session);
}
#[Route(path: '/admin/expense_report/new', name: 'admin_expense_report_new', methods: ['GET', 'POST'])]
public function new(Factory $factory, EntityManager $entityManager, Request $request): Response
{
return $this->doNew($factory->create($this->getUser()), $entityManager, $request);
}
#[Route(path: '/admin/expense_report/show/{entity}', name: 'admin_expense_report_show', methods: ['GET'])]
public function show(Entity $entity): Response
{
if (!$this->isGranted('ROLE_TREASURER')) {
if ($entity->getUser()->getId() !== $this->getUser()->getId()) {
throw $this->createAccessDeniedException();
}
}
return $this->doShow($entity);
}
#[Route(path: '/admin/expense_report/filter', name: 'admin_expense_report_filter', methods: ['GET'])]
public function filter(Session $session): Response
{
return $this->doFilter($session);
}
#[Route(path: '/admin/expense_report/edit/{entity}', name: 'admin_expense_report_edit', methods: ['GET', 'POST'])]
public function edit(Entity $entity, EntityManager $entityManager, Request $request): Response
{
if (!$this->isGranted('ROLE_TREASURER')) {
if ($entity->getUser()->getId() !== $this->getUser()->getId()) {
throw $this->createAccessDeniedException();
}
if ($entity->getIsRequestedPayment()) {
return $this->redirectToRoute('admin_expense_report_show', [
'entity' => $entity->getId(),
]);
}
}
if (!$entity->getIsRequestedPayment()) {
$form = $this->createFormBuilder()
->add('message', TextareaType::class, [
'required' => false,
'label' => 'Message',
'help' => 'Message à ajouter dans le mail de notification (optionnel)',
])
->getForm()
->createView()
;
$route = 'admin_expense_report_request_payment';
$tokenName = 'request_payment';
} elseif ($entity->getIsRequestedPayment() && !$entity->getIsPaid()) {
$form = $this->createFormBuilder()
->add('message', TextareaType::class, [
'required' => false,
'label' => 'Message',
'help' => 'Message à ajouter dans le mail de notification (optionnel)',
])
->getForm()
->createView()
;
$route = 'admin_expense_report_paid';
$tokenName = 'paid';
$form2 = $this->createFormBuilder()
->add('message', TextareaType::class, [
'required' => false,
'label' => 'Message',
'help' => 'Message à ajouter dans le mail de notification (optionnel)',
])
->getForm()
->createView()
;
$route2 = 'admin_expense_report_missing_proofs';
$tokenName2 = 'missingProofs';
}
if (isset($form)) {
$this->getConfiguration()
->addViewData('edit', 'mailFormRoute', $route)
->addViewData('edit', 'mailFormTokenName', $tokenName)
->addViewData('edit', 'mailForm', $form)
;
}
if (isset($form2)) {
$this->getConfiguration()
->addViewData('edit', 'mail2FormRoute', $route2)
->addViewData('edit', 'mail2FormTokenName', $tokenName2)
->addViewData('edit', 'mail2Form', $form2)
;
}
return $this->doEdit($entity, $entityManager, $request, [$this, 'beforeUpdate']);
}
#[Route(path: '/admin/expense_report/request_payment/{entity}/{token}', name: 'admin_expense_report_request_payment', methods: ['POST'])]
public function requestPayment(
Entity $entity,
string $token,
EntityManager $entityManager,
Request $request,
EventDispatcherInterface $eventDispatcher
): Response {
if (!$this->isGranted('ROLE_TREASURER')) {
if ($entity->getUser()->getId() !== $entity->getUser()->getId()) {
throw $this->createAccessDeniedException();
}
}
if (!$this->isCsrfTokenValid('request_payment', $token)) {
throw $this->createAccessDeniedException();
}
if ($entity->getTotalAmount() === 0.0) {
$this->addFlash('warning', 'Cette action est interdite car le total de la note de frais est 0.');
return $this->redirectToRoute('admin_expense_report_edit', [
'entity' => $entity->getId(),
]);
}
$message = $request->request->get('form')['message'] ?? null;
$entity->setIsRequestedPayment(true);
$entityManager->update($entity);
$eventDispatcher->dispatch(new EntityManagerEvent($entity, [
'message' => $message,
'user' => $this->getUser(),
]), 'expense_report.requested_payment');
$this->addFlash('success', 'La demande a été envoyée.');
return $this->redirectToRoute('admin_expense_report_show', [
'entity' => $entity->getId(),
]);
}
#[Route(path: '/admin/expense_report/paid/{entity}/{token}', name: 'admin_expense_report_paid', methods: ['POST'])]
public function paid(
Entity $entity,
string $token,
EntityManager $entityManager,
Request $request,
EventDispatcherInterface $eventDispatcher
): Response {
if (!$this->isGranted('ROLE_TREASURER')) {
throw $this->createAccessDeniedException();
}
if (!$this->isCsrfTokenValid('paid', $token)) {
throw $this->createAccessDeniedException();
}
if ($entity->getTotalAmount() === 0.0) {
$this->addFlash('warning', 'Cette action est interdite car le total de la note de frais est 0.');
return $this->redirectToRoute('admin_expense_report_edit', [
'entity' => $entity->getId(),
]);
}
$message = $request->request->get('form')['message'] ?? null;
$entity->setIsPaid(true);
if (!$entity->getPaidAt()) {
$entity->setPaidAt(new \DateTime());
}
$entityManager->update($entity);
$eventDispatcher->dispatch(new EntityManagerEvent($entity, [
'message' => $message,
'user' => $this->getUser(),
]), 'expense_report.paid');
$this->addFlash('success', 'The data has been saved.');
return $this->redirectToRoute('admin_expense_report_show', [
'entity' => $entity->getId(),
]);
}
#[Route(path: '/admin/expense_report/missing_proofs/{entity}/{token}', name: 'admin_expense_report_missing_proofs', methods: ['POST'])]
public function missingProofs(
Entity $entity,
string $token,
EntityManager $entityManager,
Request $request,
EventDispatcherInterface $eventDispatcher
): Response {
if (!$this->isGranted('ROLE_TREASURER')) {
throw $this->createAccessDeniedException();
}
if (!$this->isCsrfTokenValid('missingProofs', $token)) {
throw $this->createAccessDeniedException();
}
$message = $request->request->get('form')['message'] ?? null;
$entity->setIsRequestedPayment(false);
$entityManager->update($entity);
$eventDispatcher->dispatch(new EntityManagerEvent($entity, [
'message' => $message,
'user' => $this->getUser(),
]), 'expense_report.missing_proofs');
$this->addFlash('success', 'The data has been saved.');
return $this->redirectToRoute('admin_expense_report_edit', [
'entity' => $entity->getId(),
]);
}
protected function beforeUpdate(EntityInterface $entity, FormInterface $form, Request $request)
{
$deleteBills = $request->request->get($form->getName())['deleteBills']['bills'] ?? [];
$bills = $entity->getBills();
foreach ($bills as $key => $value) {
if (in_array($value, $deleteBills)) {
unset($bills[$key]);
$this->fs->remove($value);
}
}
$directory = sprintf(
'uploads/Notes de frais/%d/%d',
$this->getUser()->getId(),
$entity->getId()
);
$newBills = $request->files->get($form->getName())['newBills'] ?? [];
foreach ($newBills as $data) {
$this->fileUpload->handleForm(
$data['file'],
$directory,
function ($filename) use ($directory, &$bills) {
$bills[] = $directory.'/'.$filename;
},
true
);
}
$entity->setBills($bills);
}
#[Route(path: '/admin/expense_report/sort/{page}', name: 'admin_expense_report_sort', methods: ['POST'], requirements: ['page' => '\d+'])]
public function sort(RepositoryQuery $query, EntityManager $entityManager, Request $request, Session $session, int $page = 1): Response
{
return $this->doSort($page, $query, $entityManager, $request, $session);
}
#[Route(path: '/admin/expense_report/batch/{page}', name: 'admin_expense_report_batch', methods: ['POST'], requirements: ['page' => '\d+'])]
public function batch(RepositoryQuery $query, EntityManager $entityManager, Request $request, Session $session, int $page = 1): Response
{
if (!$this->isGranted('ROLE_TREASURER')) {
$query->filterByUser($this->getUser());
}
return $this->doBatch($page, $query, $entityManager, $request, $session);
}
#[Route(path: '/admin/expense_report/delete/{entity}', name: 'admin_expense_report_delete', methods: ['DELETE'])]
public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response
{
if (!$this->isGranted('ROLE_TREASURER')) {
if ($entity->getUser()->getId() !== $entity->getUser()->getId()) {
throw $this->createAccessDeniedException();
}
}
return $this->doDelete($entity, $entityManager, $request);
}
protected function getConfiguration(): CrudConfiguration
{
return CrudConfiguration::create()
->setPageTitle('index', 'Notes de frais')
->setPageTitle('edit', 'NDF #{id} de {user.displayName}')
->setPageTitle('new', 'Nouvelle note de frais')
->setPageTitle('show', 'NDF #{id} de {user.displayName}')
->setPageRoute('index', 'admin_expense_report_index')
->setPageRoute('new', 'admin_expense_report_new')
->setPageRoute('edit', 'admin_expense_report_edit')
->setPageRoute('show', 'admin_expense_report_show')
->setPageRoute('sort', 'admin_expense_report_sort')
->setPageRoute('batch', 'admin_expense_report_batch')
->setPageRoute('delete', 'admin_expense_report_delete')
->setPageRoute('filter', 'admin_expense_report_filter')
->setPageRoute('requestPayment', 'admin_expense_report_request_payment')
->setPageRoute('paid', 'admin_expense_report_paid')
->setFormOptions('new', [
'is_treasurer' => $this->isGranted('ROLE_TREASURER'),
])
->setFormOptions('edit', [
'is_treasurer' => $this->isGranted('ROLE_TREASURER'),
])
->setView('form', 'admin/expense_report/_form.html.twig')
->setView('show_entity', 'admin/expense_report/_show.html.twig')
->setView('edit', 'admin/expense_report/edit.html.twig')
->setView('show', 'admin/expense_report/show.html.twig')
->setForm('edit', Type::class, [])
->setForm('new', Type::class)
// ->setForm('filter', Type::class)
->setAction('index', 'edit', function (EntityInterface $entity) {
if ($entity->getIsRequestedPayment() && !$this->isGranted('ROLE_TREASURER')) {
return false;
}
return true;
})
->setAction('index', 'delete', function (EntityInterface $entity) {
if ($entity->getIsPaid() && !$this->isGranted('ROLE_TREASURER')) {
return false;
}
return true;
})
->setAction('show', 'edit', function (EntityInterface $entity) {
if ($entity->getIsRequestedPayment() && !$this->isGranted('ROLE_TREASURER')) {
return false;
}
return true;
})
->setDefaultSort('index', 'dateTo', 'desc')
->setField('index', 'Personne', Field\TextField::class, [
'property_builder' => function (EntityInterface $entity) {
return $entity->getUser()->getDisplayName();
},
'attr' => ['class' => 'col-md-3'],
])
->setField('index', 'Date from', Field\DateField::class, [
'property' => 'dateFrom',
'sort' => ['dateFrom', '.dateFrom'],
'format' => 'd/m/Y',
'attr' => ['class' => 'col-md-3'],
])
->setField('index', 'Date to', Field\DateField::class, [
'property' => 'dateTo',
'sort' => ['dateTo', '.dateTo'],
'format' => 'd/m/Y',
'attr' => ['class' => 'col-md-3'],
])
->setField('index', 'Statut', Field\ButtonField::class, [
'property_builder' => function (EntityInterface $entity) {
if ($entity->getIsPaid()) {
return 'Payée';
}
if ($entity->getIsRequestedPayment()) {
return 'En attente de paiement';
}
return 'Brouillon';
},
'attr' => ['class' => 'col-md-3'],
'button_attr_builder' => function (EntityInterface $entity) {
$class = 'light';
if ($entity->getIsPaid()) {
$class = 'success';
} elseif ($entity->getIsRequestedPayment()) {
$class = 'warning';
}
return ['class' => 'btn btn-sm btn-'.$class];
},
])
->setBatchAction('index', 'delete', 'Delete', function (EntityInterface $entity, EntityManager $manager) {
if ($entity->getIsPaid() && !$this->isGranted('ROLE_TREASURER')) {
return;
}
$manager->delete($entity);
})
;
}
protected function getSection(): string
{
return 'expense_report';
}
}