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'; } }