ソースを参照

Refactors new structure trial request mailers

Refactors and renames mailer builders and models related to the new structure artist premium trial request process.

This change introduces separate builders for:
- Notifying the sales administration about a new trial request.
- Confirming the trial request and providing account creation instructions to the representative.
- Sending a token validation email.

The refactoring enhances clarity and maintainability by grouping related classes and models into dedicated namespaces.

Adds a new email template for account creation confirmation.
Olivier Massot 5 ヶ月 前
コミット
d1ff7beb99

+ 60 - 0
src/Service/Mailer/Builder/Shop/NewStructureArtistPremium/ConfirmationToRepresentativeBuilder.php

@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Service\Mailer\Builder\Shop\NewStructureArtistPremium;
+
+use App\Entity\Access\Access;
+use App\Enum\Core\EmailSendingTypeEnum;
+use App\Service\Mailer\Email;
+use App\Service\Mailer\Model\MailerModelInterface;
+use App\Service\Mailer\Model\Shop\NewStructureArtistPremium\ConfirmationToRepresentativeModel;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\ORM\EntityManagerInterface;
+use App\Service\Mailer\Builder\AbstractBuilder;
+use App\Service\Mailer\Builder\BuilderInterface;
+
+/**
+ * Classe NewStructureArtistPremiumTrialRequestAccountCreationBuilder qui est chargé de construire l'Email
+ * d'accès au compte essai Opentalent Artist Premium.
+ */
+class ConfirmationToRepresentativeBuilder extends AbstractBuilder implements BuilderInterface
+{
+    public function __construct(
+        private readonly EntityManagerInterface $entityManager,
+        private readonly string $opentalentNoReplyEmailAddress,
+    ) {
+    }
+
+    public function support(MailerModelInterface $mailerModel): bool
+    {
+        return $mailerModel instanceof ConfirmationToRepresentativeModel;
+    }
+
+    /**
+     * @param ConfirmationToRepresentativeModel $mailerModel
+     */
+    public function build(MailerModelInterface $mailerModel): ArrayCollection
+    {
+        $author = $this->entityManager->getRepository(Access::class)->find($mailerModel->getSenderId());
+
+        $context = [
+            'trialRequest' => $mailerModel->getTrialRequest(),
+            'accountCreationUrl' => $mailerModel->getAccountCreationUrl(),
+            'faqUrl' => $mailerModel->getFaqUrl(),
+        ];
+
+        $content = $this->render('shop/new-structure-artist-premium-trial-account-creation', $context);
+
+        $email = (new Email())
+            ->setEmailEntity($this->buildEmailEntity('Accédez à votre compte essai Opentalent Artist Premium', $author, $content))
+            ->setContent($content)
+            ->setFrom($this->opentalentNoReplyEmailAddress)
+            ->setFromName('Opentalent');
+
+        // Add recipient as a string (direct email address)
+        $this->addRecipient($email, $mailerModel->getTrialRequest()->getRepresentativeEmail(), EmailSendingTypeEnum::TO);
+
+        return new ArrayCollection([$email]);
+    }
+}

+ 7 - 5
src/Service/Mailer/Builder/NewStructureArtistPremiumTrialRequestSalesAdminBuilder.php → src/Service/Mailer/Builder/Shop/NewStructureArtistPremium/NotificationToSalesAdminBuilder.php

@@ -2,21 +2,23 @@
 
 declare(strict_types=1);
 
-namespace App\Service\Mailer\Builder;
+namespace App\Service\Mailer\Builder\Shop\NewStructureArtistPremium;
 
 use App\Entity\Access\Access;
 use App\Enum\Core\EmailSendingTypeEnum;
 use App\Service\Mailer\Email;
 use App\Service\Mailer\Model\MailerModelInterface;
-use App\Service\Mailer\Model\NewStructureArtistPremiumTrialRequestSalesAdminModel;
+use App\Service\Mailer\Model\Shop\NewStructureArtistPremium\NotificationToSalesAdminModel;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\ORM\EntityManagerInterface;
+use App\Service\Mailer\Builder\AbstractBuilder;
+use App\Service\Mailer\Builder\BuilderInterface;
 
 /**
  * Classe NewStructureArtistPremiumTrialRequestSalesAdminBuilder qui est chargé de construire l'Email
  * d'information à l'administration des ventes concernant une demande d'essai artist premium pour une nouvelle structure.
  */
-class NewStructureArtistPremiumTrialRequestSalesAdminBuilder extends AbstractBuilder implements BuilderInterface
+class NotificationToSalesAdminBuilder extends AbstractBuilder implements BuilderInterface
 {
     public function __construct(
         private readonly EntityManagerInterface $entityManager,
@@ -26,11 +28,11 @@ class NewStructureArtistPremiumTrialRequestSalesAdminBuilder extends AbstractBui
 
     public function support(MailerModelInterface $mailerModel): bool
     {
-        return $mailerModel instanceof NewStructureArtistPremiumTrialRequestSalesAdminModel;
+        return $mailerModel instanceof NotificationToSalesAdminModel;
     }
 
     /**
-     * @param NewStructureArtistPremiumTrialRequestSalesAdminModel $mailerModel
+     * @param NotificationToSalesAdminModel $mailerModel
      */
     public function build(MailerModelInterface $mailerModel): ArrayCollection
     {

+ 7 - 5
src/Service/Mailer/Builder/NewStructureArtistPremiumTrialRequestValidationBuilder.php → src/Service/Mailer/Builder/Shop/TokenValidationBuilder.php

@@ -2,20 +2,22 @@
 
 declare(strict_types=1);
 
-namespace App\Service\Mailer\Builder;
+namespace App\Service\Mailer\Builder\Shop;
 
 use App\Entity\Access\Access;
 use App\Enum\Core\EmailSendingTypeEnum;
+use App\Service\Mailer\Builder\AbstractBuilder;
+use App\Service\Mailer\Builder\BuilderInterface;
 use App\Service\Mailer\Email;
 use App\Service\Mailer\Model\MailerModelInterface;
-use App\Service\Mailer\Model\NewStructureArtistPremiumTrialRequestValidationModel;
+use App\Service\Mailer\Model\Shop\TokenValidationModel;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\ORM\EntityManagerInterface;
 
 /**
  * Classe NewStructureTrialRequestValidationBuilder qui est chargé de construire l'Email de validation d'une demande d'essai de nouvelle structure.
  */
-class NewStructureArtistPremiumTrialRequestValidationBuilder extends AbstractBuilder implements BuilderInterface
+class TokenValidationBuilder extends AbstractBuilder implements BuilderInterface
 {
     public function __construct(
         private readonly EntityManagerInterface $entityManager,
@@ -25,11 +27,11 @@ class NewStructureArtistPremiumTrialRequestValidationBuilder extends AbstractBui
 
     public function support(MailerModelInterface $mailerModel): bool
     {
-        return $mailerModel instanceof NewStructureArtistPremiumTrialRequestValidationModel;
+        return $mailerModel instanceof TokenValidationModel;
     }
 
     /**
-     * @param NewStructureArtistPremiumTrialRequestValidationModel $mailerModel
+     * @param TokenValidationModel $mailerModel
      */
     public function build(MailerModelInterface $mailerModel): ArrayCollection
     {

+ 56 - 0
src/Service/Mailer/Model/Shop/NewStructureArtistPremium/ConfirmationToRepresentativeModel.php

@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Service\Mailer\Model\Shop\NewStructureArtistPremium;
+
+use App\ApiResources\Shop\NewStructureArtistPremiumTrialRequest;
+use App\Service\Mailer\Model\AbstractMailerModel;
+use App\Service\Mailer\Model\MailerModelInterface;
+
+/**
+ * Classe NewStructureArtistPremiumTrialRequestAccountCreationModel qui conserve les données pour construire le mail
+ * d'accès au compte essai Opentalent Artist Premium.
+ */
+class ConfirmationToRepresentativeModel extends AbstractMailerModel implements MailerModelInterface
+{
+    private NewStructureArtistPremiumTrialRequest $trialRequest;
+    private string $accountCreationUrl;
+    private string $faqUrl;
+
+    public function getTrialRequest(): NewStructureArtistPremiumTrialRequest
+    {
+        return $this->trialRequest;
+    }
+
+    public function setTrialRequest(NewStructureArtistPremiumTrialRequest $trialRequest): self
+    {
+        $this->trialRequest = $trialRequest;
+
+        return $this;
+    }
+
+    public function getAccountCreationUrl(): string
+    {
+        return $this->accountCreationUrl;
+    }
+
+    public function setAccountCreationUrl(string $accountCreationUrl): self
+    {
+        $this->accountCreationUrl = $accountCreationUrl;
+
+        return $this;
+    }
+
+    public function getFaqUrl(): string
+    {
+        return $this->faqUrl;
+    }
+
+    public function setFaqUrl(string $faqUrl): self
+    {
+        $this->faqUrl = $faqUrl;
+
+        return $this;
+    }
+}

+ 4 - 2
src/Service/Mailer/Model/NewStructureArtistPremiumTrialRequestSalesAdminModel.php → src/Service/Mailer/Model/Shop/NewStructureArtistPremium/NotificationToSalesAdminModel.php

@@ -2,15 +2,17 @@
 
 declare(strict_types=1);
 
-namespace App\Service\Mailer\Model;
+namespace App\Service\Mailer\Model\Shop\NewStructureArtistPremium;
 
 use App\ApiResources\Shop\NewStructureArtistPremiumTrialRequest;
+use App\Service\Mailer\Model\AbstractMailerModel;
+use App\Service\Mailer\Model\MailerModelInterface;
 
 /**
  * Classe NewStructureArtistPremiumTrialRequestSalesAdminModel qui conserve les données pour construire le mail
  * d'information à l'administration des ventes concernant une demande d'essai artist premium pour une nouvelle structure.
  */
-class NewStructureArtistPremiumTrialRequestSalesAdminModel extends AbstractMailerModel implements MailerModelInterface
+class NotificationToSalesAdminModel extends AbstractMailerModel implements MailerModelInterface
 {
     private NewStructureArtistPremiumTrialRequest $trialRequest;
 

+ 5 - 2
src/Service/Mailer/Model/NewStructureArtistPremiumTrialRequestValidationModel.php → src/Service/Mailer/Model/Shop/TokenValidationModel.php

@@ -2,12 +2,15 @@
 
 declare(strict_types=1);
 
-namespace App\Service\Mailer\Model;
+namespace App\Service\Mailer\Model\Shop;
+
+use App\Service\Mailer\Model\AbstractMailerModel;
+use App\Service\Mailer\Model\MailerModelInterface;
 
 /**
  * Classe NewStructureTrialRequestValidationModel qui conserve les données pour construire le mail de validation d'une demande d'essai de nouvelle structure.
  */
-class NewStructureArtistPremiumTrialRequestValidationModel extends AbstractMailerModel implements MailerModelInterface
+class TokenValidationModel extends AbstractMailerModel implements MailerModelInterface
 {
     private string $token;
     private string $representativeEmail;

+ 30 - 6
src/Service/Shop/ShopService.php

@@ -7,17 +7,16 @@ namespace App\Service\Shop;
 use App\ApiResources\Organization\OrganizationCreationRequest;
 use App\ApiResources\Shop\NewStructureArtistPremiumTrialRequest;
 use App\Entity\Organization\Organization;
-use App\Entity\Organization\Subdomain;
 use App\Entity\Shop\ShopRequest;
 use App\Enum\Access\AccessIdsEnum;
 use App\Enum\Organization\SettingsProductEnum;
 use App\Enum\Shop\ShopRequestStatus;
 use App\Enum\Shop\ShopRequestType;
 use App\Message\Message\Shop\NewStructureArtistPremiumTrial;
-use App\Service\Dolibarr\DolibarrApiService;
-use App\Service\Dolibarr\DolibarrUtils;
 use App\Service\Mailer\Mailer;
-use App\Service\Mailer\Model\NewStructureArtistPremiumTrialRequestValidationModel;
+use App\Service\Mailer\Model\Shop\NewStructureArtistPremium\ConfirmationToRepresentativeModel;
+use App\Service\Mailer\Model\Shop\NewStructureArtistPremium\NotificationToSalesAdminModel;
+use App\Service\Mailer\Model\Shop\TokenValidationModel;
 use App\Service\Organization\OrganizationFactory;
 use App\Service\Utils\DatesUtils;
 use App\Service\Utils\UrlBuilder;
@@ -152,7 +151,7 @@ class ShopService
 
         $data = $shopRequest->getData();
 
-        $model = new NewStructureArtistPremiumTrialRequestValidationModel();
+        $model = new TokenValidationModel();
         $model
             ->setToken($shopRequest->getToken())
             ->setRepresentativeEmail($data['representativeEmail'] ?? '')
@@ -206,6 +205,9 @@ class ShopService
         // Send email to sales administration
         $this->sendMailToSalesAdministration($trialRequest);
 
+        // Send email to representative
+        $this->sendConfirmationMailToRepresentative($trialRequest);
+
         $this->logger->info('Successfully processed NewStructureArtistPremiumTrial for token: '.$token);
     }
 
@@ -285,7 +287,7 @@ class ShopService
     protected function sendMailToSalesAdministration(NewStructureArtistPremiumTrialRequest $trialRequest): void
     {
         // Create the email model
-        $model = new Model\NewStructureArtistPremiumTrialRequestSalesAdminModel();
+        $model = new NotificationToSalesAdminModel();
         $model
             ->setTrialRequest($trialRequest)
             ->setSenderId(AccessIdsEnum::ADMIN_2IOPENSERVICE->value);
@@ -293,4 +295,26 @@ class ShopService
         // Send the email to the sales administration
         $this->mailer->main($model);
     }
+
+    /**
+     * Envoie un email au représentant pour l'informer que sa demande d'essai artist premium a été validée
+     * et lui fournir un lien pour créer son compte et accéder au logiciel.
+     *
+     * @param NewStructureArtistPremiumTrialRequest $trialRequest La demande d'essai
+     *
+     * @throws TransportExceptionInterface
+     */
+    protected function sendConfirmationMailToRepresentative(NewStructureArtistPremiumTrialRequest $trialRequest): void
+    {
+        // Create the email model
+        $model = new ConfirmationToRepresentativeModel();
+        $model
+            ->setTrialRequest($trialRequest)
+            ->setAccountCreationUrl(UrlBuilder::concat($this->publicBaseUrl, ['/account/create']))
+            ->setFaqUrl(UrlBuilder::concat($this->publicBaseUrl, ['/faq/opentalent-artist']))
+            ->setSenderId(AccessIdsEnum::ADMIN_2IOPENSERVICE->value);
+
+        // Send the email to the representative
+        $this->mailer->main($model);
+    }
 }

+ 35 - 0
templates/emails/shop/new-structure-artist-premium-trial-account-creation.html.twig

@@ -0,0 +1,35 @@
+{% extends '@templates/emails/base.html.twig' %}
+
+{% block title %}Accédez à votre compte essai Opentalent Artist Premium{% endblock %}
+
+{% block content %}
+    <h1>Bonjour {{ trialRequest.representativeFirstName }},</h1>
+
+    <p>Votre demande d'essai pour Opentalent Artist Premium a été validée.</p>
+
+    <p>Pour finaliser votre inscription et accéder à votre espace, veuillez cliquer sur le lien ci-dessous :</p>
+
+    <p style="text-align: center; margin: 30px 0;">
+        <a href="{{ accountCreationUrl }}" style="background-color: #4CAF50; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 10px;">
+            Créer mon compte et accéder au logiciel
+        </a>
+    </p>
+
+    <p>Sur cette page, vous pourrez définir votre identifiant et votre mot de passe. Une fois ces informations renseignées, vous serez automatiquement connecté à votre compte.</p>
+
+    <p>Besoin d'aide ? Consultez notre FAQ complète pour découvrir toutes les fonctionnalités du logiciel et trouver les réponses à vos questions :</p>
+
+    <p style="text-align: center; margin: 30px 0;">
+        <a href="{{ faqUrl }}" style="background-color: #008CBA; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 10px;">
+            Tout savoir Opentalent Artist
+        </a>
+    </p>
+
+    <p>À bientôt<br>L'équipe Opentalent</p>
+
+    <hr>
+    <p style="font-size: 12px; color: #666;">
+        Pour ne plus recevoir de mail marketing, <a href="#">désabonnez-vous</a><br>
+        Réseaux sociaux : <a href="#">Facebook</a> / <a href="#">Linkedin</a> / <a href="#">Youtube</a>
+    </p>
+{% endblock %}