Feat: Implement email notification about new disposition

This commit is contained in:
Björn Fromme
2023-11-08 11:08:27 +01:00
parent c4e0ef7d5a
commit 342119a456
14 changed files with 129 additions and 69 deletions
+2
View File
@@ -40,6 +40,8 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
MAILER_DSN=null://null
###< symfony/mailer ###
APP_BASE_URI=https://myep-team.ddev.site
APP_BPN_USER=
APP_BPN_PASSWORD=
APP_BPN_ENDPOINT=
+15 -10
View File
@@ -9,18 +9,20 @@
<mj-style>
h1 {
font-weight: bold;
font-size: 32px;
line-height: 36px;
margin-bottom: 0;
padding-bottom: 16px;
}
h2 {
font-weight: normal;
font-size: 24px;
line-height: 28px;
margin-bottom: 0;
padding-bottom: 8px;
}
h2 {
font-weight: normal;
font-size: 20px;
line-height: 24px;
margin-bottom: 0;
padding-bottom: 0;
}
p {
font-size: 16px;
padding-bottom: 16px;
}
p.small {
@@ -43,11 +45,14 @@
padding: 8px 16px;
border-radius: 4px;
}
strong {
font-weight: bold;
}
</mj-style>
</mj-head>
<mj-body background-color="#666666">
<mj-hero mode="fluid-height" height="285px" background-color="#FFFFFF" padding-top="20px" padding-bottom="20px">
<mj-image src="{{ email.image('@images/logo.png') }}" width="200px" align="left" alt="Logo E&P" />
<mj-hero mode="fluid-height" height="285px" background-color="#FFFFFF" padding-top="10px" padding-bottom="10px">
<mj-image src="{{ email.image('@images/logo.png') }}" width="160px" align="left" alt="Logo E&amp;P" />
</mj-hero>
<mj-section background-color="#FFFFFF" border-top="1px solid #3d8ccb">
<mj-column>
@@ -65,7 +70,7 @@
</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto culpa delectus dolores
earum eius fugiat in nesciunt quas quidem vitae?
<strong>earum eius fugiat in nesciunt quas quidem vitae</strong>?
</p>
<p>
<a href="#" class="button">
+3
View File
@@ -18,6 +18,9 @@ framework:
php_errors:
log: true
router:
default_uri: '%env(APP_BASE_URI)%'
when@test:
framework:
test: true
+2 -2
View File
@@ -13,10 +13,10 @@ framework:
max_retries: 3
multiplier: 2
failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'
sync: 'sync://'
routing:
Symfony\Component\Mailer\Messenger\SendEmailMessage: async
Symfony\Component\Mailer\Messenger\SendEmailMessage: sync
Symfony\Component\Notifier\Message\ChatMessage: async
Symfony\Component\Notifier\Message\SmsMessage: async
@@ -4,17 +4,20 @@ namespace App\Controller\Admin\Application;
use App\Entity\Application;
use App\Entity\Disposition;
use App\Event\DispositionCreatedEvent;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class DisposeController extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly EventDispatcherInterface $eventDispatcher,
private readonly LoggerInterface $logger
) {
}
@@ -30,6 +33,8 @@ class DisposeController extends AbstractController
$this->entityManager->remove($application);
$this->entityManager->flush();
$this->eventDispatcher->dispatch(new DispositionCreatedEvent($disposition), DispositionCreatedEvent::NAME);
$this->addFlash('success', 'Der Teamer wurde eingeteilt');
$this->logger->info('Create disposition', [
'disposition_id' => $disposition->getId(),
-28
View File
@@ -1,28 +0,0 @@
<?php
namespace App\Email;
use App\Entity\User;
use Psr\Log\LoggerInterface;
class WelcomeEmailMailer
{
public function __construct(private readonly Mailer $mailer, private readonly LoggerInterface $logger)
{}
public function send(User $user): void
{
$this->mailer->createAndSendEmail([
'user' => $user,
], [
'to' => $user->getEmail(),
'subject' => 'Willkommen bei MyE&P Team',
'template' => 'email/welcome.html.twig',
]);
$this->logger->info('Send welcome email', [
'user_id' => $user->getId(),
'user_email' => $user->getEmail(),
]);
}
}
+2 -3
View File
@@ -51,11 +51,10 @@ class Destination implements TimestampableEntityInterface, SoftDeletableEntityIn
public function __toString(): string
{
return sprintf('%s - %s: %s, %s',
return sprintf('%s - %s %s',
$this->getDateFrom()->format('d.m.y'),
$this->getDateTo()->format('d.m.y'),
$this->getProduct(),
$this->getHotel()
$this->getProduct()
);
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Event;
use App\Entity\Disposition;
use Symfony\Contracts\EventDispatcher\Event;
class DispositionCreatedEvent extends Event
{
public const NAME = 'disposition.created';
public function __construct(private readonly Disposition $disposition)
{}
public function getDisposition(): Disposition
{
return $this->disposition;
}
}
@@ -0,0 +1,35 @@
<?php
namespace App\EventListener;
use App\Email\Mailer;
use App\Event\DispositionCreatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class EmailNotificationSubscriber implements EventSubscriberInterface
{
public function __construct(private readonly Mailer $mailer)
{
}
public static function getSubscribedEvents(): array
{
return [
DispositionCreatedEvent::NAME => 'onDispositionCreated',
];
}
public function onDispositionCreated(DispositionCreatedEvent $event): void
{
$disposition = $event->getDisposition();
$teamer = $disposition->getTeamer();
$this->mailer->createAndSendEmail([
'disposition' => $disposition,
], [
'to' => $teamer->getCommunication()->getEmail(),
'subject' => 'Dein Einsatz wurde angenommen',
'template' => 'email/application_accepted.html.twig',
]);
}
}
@@ -12,7 +12,7 @@
Destination
</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
{{ assignment.destination.product }}, {{ assignment.destination.hotel }}
{{ assignment.destination.product }}
</dd>
</div>
<div class="py-6 first:pt-0 last:pb-0 sm:grid sm:grid-cols-3 sm:gap-4">
@@ -13,7 +13,7 @@
Destination
</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">
{{ assignment.destination.product }}, {{ assignment.destination.hotel }}
{{ assignment.destination.product }}
</dd>
</div>
<div class="py-6 first:pt-0 last:pb-0 sm:grid sm:grid-cols-3 sm:gap-4">
@@ -0,0 +1,29 @@
{% extends 'email/layout.html.twig' %}
{% block body %}
<h1>
Herzlichen Glückwunsch!
</h1>
<p>
<strong>
Dein Einsatz <a href="{{ url('app_teamer_disposition_detail', { 'uuid': disposition.uuid }) }}">{{ disposition.assignment.destination}}</a>
wurde angenommen!
</strong>
</p>
<p>
Schau einmal in das <a href="{{ url('app_teamer_disposition_detail', { 'uuid': disposition.uuid }) }}">My E&amp;P-Team Portal</a>,
um die Einsatzdetails einzusehen und deinen Honorarvertrag zu unterschreiben.
</p>
<p>
Mit dem Erhalt dieser E-Mail hast du 7 Tage Zeit deinen Einsatz zu bestätigen, indem du den unterschriebenen
Vertrag hochlädst. Ist diese Frist vergangen, wird der Einsatz für deine Teamkolleg:innen freigeschaltet.
</p>
<p>
Schön, dass du dabei bist und ganz viel Spaß in den Bergen! 😊
</p>
<p>
<a href="{{ url('app_teamer_index') }}" class="button">
Zum Portal
</a>
</p>
{% endblock %}
+15 -9
View File
@@ -105,20 +105,22 @@
<style type="text/css">
h1 {
font-weight: bold;
font-size: 32px;
line-height: 36px;
font-size: 24px;
line-height: 28px;
margin-bottom: 0;
padding-bottom: 16px;
padding-bottom: 8px;
}
h2 {
font-weight: normal;
font-size: 24px;
line-height: 28px;
font-size: 20px;
line-height: 24px;
margin-bottom: 0;
padding-bottom: 0;
}
p {
font-size: 16px;
padding-bottom: 16px;
}
@@ -146,6 +148,10 @@
border-radius: 4px;
}
strong {
font-weight: bold;
}
</style>
</head>
@@ -158,7 +164,7 @@
<tbody>
<tr style="vertical-align:top;">
<td style="width:0.01%;padding-bottom:NaN%;mso-padding-bottom-alt:0;" />
<td style="background:#FFFFFF;background-position:center center;background-repeat:no-repeat;padding:0px;padding-top:20px;padding-bottom:20px;vertical-align:top;">
<td style="background:#FFFFFF;background-position:center center;background-repeat:no-repeat;padding:0px;padding-top:10px;padding-bottom:10px;vertical-align:top;">
<!--[if mso | IE]><table border="0" cellpadding="0" cellspacing="0" style="width:600px;" width="600" ><tr><td style=""><![endif]-->
<div class="mj-hero-content" style="margin:0px auto;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;margin:0px;">
@@ -172,8 +178,8 @@
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;">
<tbody>
<tr>
<td style="width:200px;">
<img alt="Logo E&P" src="{{ email.image('@images/logo.png') }}" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" width="200" height="auto" />
<td style="width:160px;">
<img alt="Logo E&amp;P" src="{{ email.image('@images/logo.png') }}" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" width="160" height="auto" />
</td>
</tr>
</tbody>
@@ -209,7 +215,7 @@
<div style="font-family:Lato, Verdana, Arial, 'Helvetica neue', sans-serif;font-size:16px;line-height:24px;text-align:left;color:#666666;">{% block body %} <h1> Lorem ipsum dolor sit amet </h1>
<p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto culpa delectus dolores earum eius fugiat in nesciunt quas quidem vitae? </p>
<h2> Lorem ipsum dolor </h2>
<p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto culpa delectus dolores earum eius fugiat in nesciunt quas quidem vitae? </p>
<p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto culpa delectus dolores <strong>earum eius fugiat in nesciunt quas quidem vitae</strong>? </p>
<p>
<a href="#" class="button"> Button </a>
</p>
-15
View File
@@ -1,15 +0,0 @@
{% extends 'email/layout.html.twig' %}
{% block body %}
<h1>
Willkommen bei MyE&P Team
</h1>
<p>
Hallo {{ user.firstName }},
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid asperiores atque, commodi deleniti
dignissimos dolorum earum ex facere facilis necessitatibus non omnis pariatur possimus quas repudiandae sit
soluta tenetur, voluptatem.
</p>
{% endblock %}