feat: email notifications about uploaded invoices to management
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Event;
|
||||
|
||||
use App\Entity\Upload;
|
||||
use Symfony\Contracts\EventDispatcher\Event;
|
||||
|
||||
class DocumentUploadedEvent extends Event
|
||||
{
|
||||
public const NAME = 'document.uploaded';
|
||||
|
||||
public function __construct(private readonly Upload $document)
|
||||
{
|
||||
}
|
||||
|
||||
public function getDocument(): Upload
|
||||
{
|
||||
return $this->document;
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{% extends 'email/layout.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
<h1>
|
||||
Honorarnote hochgeladen
|
||||
</h1>
|
||||
<p>
|
||||
<strong>{{ disposition.teamer }}</strong> hat eine Honorarnote zum Einsatz
|
||||
<strong>{{ disposition.assignment.jobProfile.name }} {{ disposition.assignment.destination}}</strong>
|
||||
hochgeladen.
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{ url('app_teamer_index') }}" class="button">
|
||||
Zum Portal
|
||||
</a>
|
||||
</p>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user