From 8d0babba14d4b9034d8c48bd22c5c799b045cd3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Thu, 4 Apr 2024 15:08:52 +0200 Subject: [PATCH] feat: email notifications about uploaded invoices to management --- .../Teamer/Disposition/DetailController.php | 9 ++++- src/Event/DocumentUploadedEvent.php | 20 ++++++++++ .../EmailNotificationSubscriber.php | 39 ++++++++++++++++++- src/Repository/UserRepository.php | 18 +++++++++ templates/email/invoice_uploaded.html.twig | 17 ++++++++ 5 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 src/Event/DocumentUploadedEvent.php create mode 100644 templates/email/invoice_uploaded.html.twig diff --git a/src/Controller/Teamer/Disposition/DetailController.php b/src/Controller/Teamer/Disposition/DetailController.php index 7e03dbf..bca74eb 100644 --- a/src/Controller/Teamer/Disposition/DetailController.php +++ b/src/Controller/Teamer/Disposition/DetailController.php @@ -6,6 +6,7 @@ use App\Controller\Traits\ReturnUrlTrait; use App\Entity\Disposition; use App\Entity\Upload; use App\Entity\User; +use App\Event\DocumentUploadedEvent; use App\Form\TeamerDispositionType; use App\Model\UploadSessionDto; use App\Service\Upload\UploadHandler; @@ -18,6 +19,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Workflow\WorkflowInterface; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; class DetailController extends AbstractController { @@ -28,6 +30,7 @@ class DetailController extends AbstractController private readonly EntityManagerInterface $entityManager, #[Target('disposition')] private readonly WorkflowInterface $workflow, + private readonly EventDispatcherInterface $eventDispatcher, private readonly LoggerInterface $logger ) { } @@ -63,7 +66,7 @@ class DetailController extends AbstractController return $this->render('teamer/disposition/detail.html.twig', [ 'disposition' => $disposition, - 'form' => $form, + 'form' => $form->createView(), 'returnUrl' => $this->getReturnUrl($request, 'app_teamer_index'), ]); } @@ -93,6 +96,8 @@ class DetailController extends AbstractController $this->logger->info('Upload contract', [ 'user' => $user->getUserIdentifier(), ]); + + $this->eventDispatcher->dispatch(new DocumentUploadedEvent($upload), DocumentUploadedEvent::NAME); } private function uploadInvoice(Disposition $disposition, UploadSessionDto $uploadSession): void @@ -120,5 +125,7 @@ class DetailController extends AbstractController $this->logger->info('Upload invoice', [ 'user' => $user->getUserIdentifier(), ]); + + $this->eventDispatcher->dispatch(new DocumentUploadedEvent($upload), DocumentUploadedEvent::NAME); } } \ No newline at end of file diff --git a/src/Event/DocumentUploadedEvent.php b/src/Event/DocumentUploadedEvent.php new file mode 100644 index 0000000..f9a8395 --- /dev/null +++ b/src/Event/DocumentUploadedEvent.php @@ -0,0 +1,20 @@ +document; + } +} \ No newline at end of file diff --git a/src/EventListener/EmailNotificationSubscriber.php b/src/EventListener/EmailNotificationSubscriber.php index b943431..2a510ae 100644 --- a/src/EventListener/EmailNotificationSubscriber.php +++ b/src/EventListener/EmailNotificationSubscriber.php @@ -3,19 +3,25 @@ namespace App\EventListener; use App\Email\Mailer; +use App\Entity\Upload; use App\Event\DispositionCreatedEvent; +use App\Event\DocumentUploadedEvent; +use App\Repository\UserRepository; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class EmailNotificationSubscriber implements EventSubscriberInterface { - public function __construct(private readonly Mailer $mailer) - { + public function __construct( + private readonly Mailer $mailer, + private readonly UserRepository $userRepository + ) { } public static function getSubscribedEvents(): array { return [ DispositionCreatedEvent::NAME => 'onDispositionCreated', + DocumentUploadedEvent::NAME => 'onDocumentUploaded', ]; } @@ -32,4 +38,33 @@ class EmailNotificationSubscriber implements EventSubscriberInterface 'template' => 'email/application_accepted.html.twig', ]); } + + public function onDocumentUploaded(DocumentUploadedEvent $event): void + { + $document = $event->getDocument(); + + if (Upload::TYPE_INVOICE === $document->getType()) { + $disposition = $document->getDisposition(); + $hotelCode = $disposition + ->getAssignment() + ->getDestination() + ->getHotelCode() + ; + + $managers = $this + ->userRepository + ->getUsersByRoleAndHotelCode('ROLE_MANAGER', $hotelCode) + ; + + foreach ($managers as $manager) { + $this->mailer->createAndSendEmail([ + 'disposition' => $disposition, + ], [ + 'to' => $manager->getEmail(), + 'subject' => 'Honorarnote hochgeladen', + 'template' => 'email/invoice_uploaded.html.twig', + ]); + } + } + } } \ No newline at end of file diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 86a987a..2112130 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -20,4 +20,22 @@ class UserRepository extends ServiceEntityRepository { parent::__construct($registry, User::class); } + + public function getUsersByRoleAndHotelCode(string $role, string $hotelCode): array + { + $hotelCodeBase = substr($hotelCode, 0, 3); + + $qb = $this->createQueryBuilder('user'); + + return $qb + ->where($qb->expr()->andX( + $qb->expr()->eq('user.hotelCode', ':hotelCode'), + $qb->expr()->like('user.roles', ':role') + )) + ->setParameter('hotelCode', $hotelCodeBase) + ->setParameter('role', '%"'.$role.'"%') + ->getQuery() + ->getResult() + ; + } } diff --git a/templates/email/invoice_uploaded.html.twig b/templates/email/invoice_uploaded.html.twig new file mode 100644 index 0000000..cab5011 --- /dev/null +++ b/templates/email/invoice_uploaded.html.twig @@ -0,0 +1,17 @@ +{% extends 'email/layout.html.twig' %} + +{% block body %} +

+ Honorarnote hochgeladen +

+

+ {{ disposition.teamer }} hat eine Honorarnote zum Einsatz + {{ disposition.assignment.jobProfile.name }} {{ disposition.assignment.destination}} + hochgeladen. +

+

+ + Zum Portal + +

+{% endblock %} \ No newline at end of file