浏览代码

organization deletion : add message handler and processor

Olivier Massot 1 年之前
父节点
当前提交
6965a4681b

+ 93 - 0
src/ApiResources/Organization/OrganizationDeletionRequest.php

@@ -0,0 +1,93 @@
+<?php
+
+namespace App\ApiResources\Organization;
+
+use ApiPlatform\Metadata\ApiProperty;
+use ApiPlatform\Metadata\ApiResource;
+use ApiPlatform\Metadata\Post;
+use App\Enum\Organization\LegalEnum;
+use App\Enum\Organization\OrganizationIdsEnum;
+use App\Enum\Organization\PrincipalTypeEnum;
+use App\Enum\Organization\SettingsProductEnum;
+use App\State\Processor\Organization\OrganizationCreationRequestProcessor;
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * Requête de création d'une nouvelle organisation
+ */
+#[ApiResource(
+    operations: [
+        new Post(
+            uriTemplate: '/internal/organization/delete',
+        ),
+    ],
+    processor: OrganizationDeletionRequestProcessor::class
+)]
+class OrganizationDeletionRequest
+{
+    /**
+     * Id 'bidon' ajouté par défaut pour permettre la construction
+     * de l'IRI par api platform.
+     */
+    #[ApiProperty(identifier: true)]
+    private int $id = 0;
+
+    private int $organizationId;
+
+    /**
+     * A quelle adresse email notifier la création de l'organisation, ou d'éventuelles erreurs ?
+     * @var string|null
+     */
+    #[Assert\Email(message: 'The email {{ value }} is not a valid email.')]
+    private ?string $sendConfirmationEmailAt = null;
+
+    /**
+     * For testing purposes only
+     * @var bool
+     */
+    private bool $async = true;
+
+    public function getId(): int
+    {
+        return $this->id;
+    }
+
+    public function setId(int $id): self
+    {
+        $this->id = $id;
+        return $this;
+    }
+
+    public function getOrganizationId(): int
+    {
+        return $this->organizationId;
+    }
+
+    public function setOrganizationId(int $organizationId): self
+    {
+        $this->organizationId = $organizationId;
+        return $this;
+    }
+
+    public function getSendConfirmationEmailAt(): ?string
+    {
+        return $this->sendConfirmationEmailAt;
+    }
+
+    public function setSendConfirmationEmailAt(?string $sendConfirmationEmailAt): self
+    {
+        $this->sendConfirmationEmailAt = $sendConfirmationEmailAt;
+        return $this;
+    }
+
+    public function isAsync(): bool
+    {
+        return $this->async;
+    }
+
+    public function setAsync(bool $async): self
+    {
+        $this->async = $async;
+        return $this;
+    }
+}

+ 29 - 0
src/Message/Command/OrganizationDeletionCommand.php

@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Message\Command;
+
+use App\ApiResources\Organization\OrganizationDeletionRequest;
+
+/**
+ * Transmission d'une requête de création d'organisation au service dédié.
+ */
+class OrganizationDeletionCommand
+{
+    public function __construct(
+        private OrganizationDeletionRequest $organizationDeletionRequest
+    ) {
+    }
+
+    public function getOrganizationDeletionRequest(): OrganizationDeletionRequest
+    {
+        return $this->organizationDeletionRequest;
+    }
+
+    public function setOrganizationDeletionRequest(OrganizationDeletionRequest $organizationDeletionRequest): self
+    {
+        $this->organizationDeletionRequest = $organizationDeletionRequest;
+        return $this;
+    }
+}

+ 59 - 0
src/Message/Handler/OrganizationDeletionHandler.php

@@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Message\Handler;
+
+use App\Message\Command\OrganizationCreationCommand;
+use App\Message\Command\OrganizationDeletionCommand;
+use App\Service\Organization\OrganizationFactory;
+use Symfony\Component\Mailer\MailerInterface;
+use Symfony\Component\Messenger\Attribute\AsMessageHandler;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Email as SymfonyEmail;
+use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
+use Throwable;
+
+#[AsMessageHandler(priority: 1)]
+class OrganizationDeletionHandler
+{
+    public function __construct(
+        private readonly OrganizationFactory $organizationFactory,
+        private readonly MailerInterface $symfonyMailer,
+    ) {}
+
+    /**
+     * @throws Throwable
+     * @throws TransportExceptionInterface
+     * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
+     */
+    public function __invoke(OrganizationDeletionCommand $organizationDeletionCommand): void
+    {
+        $organizationCreationRequest = $organizationDeletionCommand->getOrganizationDeletionRequest();
+        $mail = ['subject' => '', 'content' => ''];
+
+        try {
+            $this->organizationFactory->delete($organizationCreationRequest);
+
+            $mail['subject'] = 'Organization deleted';
+            $mail['content'] = 'The organization n° ' . $organizationCreationRequest->getOrganizationId() . ' has been deleted successfully.';
+
+        } catch (\Exception $e) {
+            $mail['subject'] = 'Organization deletion : an error occured';
+            $mail['content'] = 'An error occured while deleting the new organization : \n' . $e->getMessage();
+            throw $e;
+
+        } finally {
+            if ($organizationCreationRequest->getSendConfirmationEmailAt() !== null) {
+                $symfonyMail = (new SymfonyEmail())
+                    ->from('mail.report@opentalent.fr')
+                    ->replyTo('mail.report@opentalent.fr')
+                    ->returnPath(Address::create('mail.report@opentalent.fr'))
+                    ->to($organizationCreationRequest->getSendConfirmationEmailAt())
+                    ->subject($mail['subject'])
+                    ->text($mail['content']);
+                $this->symfonyMailer->send($symfonyMail);
+            }
+        }
+    }
+}

+ 48 - 0
src/State/Processor/Organization/OrganizationDeletionRequestProcessor.php

@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\State\Processor\Organization;
+
+use ApiPlatform\Metadata\Delete;
+use ApiPlatform\Metadata\Operation;
+use ApiPlatform\State\ProcessorInterface;
+use App\ApiResources\Organization\OrganizationCreationRequest;
+use App\ApiResources\Organization\OrganizationDeletionRequest;
+use App\Message\Command\OrganizationCreationCommand;
+use App\Service\Organization\OrganizationFactory;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Messenger\MessageBusInterface;
+
+class OrganizationDeletionRequestProcessor implements ProcessorInterface
+{
+    public function __construct(
+        private readonly MessageBusInterface $messageBus,
+        private readonly OrganizationFactory $organizationFactory,
+    ) {}
+
+    /**
+     * @param OrganizationDeletionRequest $organizationDeletionRequest
+     * @param mixed[]       $uriVariables
+     * @param mixed[]       $context
+     *
+     * @throws \Exception
+     */
+    public function process(mixed $organizationDeletionRequest, Operation $operation, array $uriVariables = [], array $context = []): OrganizationCreationRequest
+    {
+        if (!$operation instanceof Delete) {
+            throw new \RuntimeException('not supported', Response::HTTP_METHOD_NOT_ALLOWED);
+        }
+
+        if ($organizationDeletionRequest->isAsync()) {
+            // Send the export request to Messenger (@see App\Message\Handler\OrganizationCreationHandler)
+            $this->messageBus->dispatch(
+                new OrganizationDeletionCommand($organizationDeletionRequest)
+            );
+        } else {
+            // For testing purposes only
+            $this->organizationFactory->delete($organizationDeletionRequest);
+        }
+        return $organizationDeletionRequest;
+    }
+}