Send an email when a workflow is send to an external

- create an event subscriber to catch the workflow which arrive to a "sentExternal" step;
- add a messenger's message to handle the generation of the email;
- add a simple message, and a simple controller for viewing the document
- add dedicated tests
This commit is contained in:
2024-10-04 13:40:50 +02:00
parent 7913a377c8
commit a0b5c208eb
11 changed files with 417 additions and 4 deletions

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Workflow\EventSubscriber;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Workflow\Messenger\PostSendExternalMessage;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Workflow\Event\CompletedEvent;
use Symfony\Component\Workflow\Registry;
use Symfony\Contracts\Translation\LocaleAwareInterface;
class EntityWorkflowPrepareEmailOnSendExternalEventSubscriber implements EventSubscriberInterface, LocaleAwareInterface
{
private string $locale;
public function __construct(private readonly Registry $registry, private readonly MessageBusInterface $messageBus) {}
public static function getSubscribedEvents(): array
{
return [
'workflow.completed' => 'onWorkflowCompleted',
];
}
public function onWorkflowCompleted(CompletedEvent $event): void
{
$entityWorkflow = $event->getSubject();
if (!$entityWorkflow instanceof EntityWorkflow) {
return;
}
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
$store = $workflow->getMetadataStore();
$mustSend = false;
foreach ($event->getTransition()->getTos() as $to) {
$metadata = $store->getPlaceMetadata($to);
if ($metadata['isSentExternal'] ?? false) {
$mustSend = true;
}
}
if ($mustSend) {
$this->messageBus->dispatch(new PostSendExternalMessage($entityWorkflow->getId(), $this->getLocale()));
}
}
public function setLocale(string $locale): void
{
$this->locale = $locale;
}
public function getLocale(): string
{
return $this->locale;
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Workflow\Messenger;
class PostSendExternalMessage
{
public function __construct(
public readonly int $entityWorkflowId,
public readonly string $lang,
) {}
}

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Workflow\Messenger;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSend;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Mime\BodyRendererInterface;
final readonly class PostSendExternalMessageHandler implements MessageHandlerInterface
{
public function __construct(
private EntityWorkflowRepository $entityWorkflowRepository,
private MailerInterface $mailer,
private BodyRendererInterface $bodyRenderer,
) {}
public function __invoke(PostSendExternalMessage $message): void
{
$entityWorkflow = $this->entityWorkflowRepository->find($message->entityWorkflowId);
if (null === $entityWorkflow) {
throw new UnrecoverableMessageHandlingException(sprintf('Entity workflow with id %d not found', $message->entityWorkflowId));
}
foreach ($entityWorkflow->getCurrentStep()->getSends() as $send) {
$this->sendEmailToDestinee($send, $message);
}
}
private function sendEmailToDestinee(EntityWorkflowSend $send, PostSendExternalMessage $message): void
{
$email = new TemplatedEmail();
$email
->to($send->getDestineeThirdParty()?->getEmail() ?? $send->getDestineeEmail())
->htmlTemplate('@ChillMain/Workflow/workflow_send_external_email_to_destinee.html.twig')
->context([
'send' => $send,
'lang' => $message->lang,
]);
$this->bodyRenderer->render($email);
$this->mailer->send($email);
}
}