✨ feat(command): Crée une commande pour l'envoi automatisé d'emails de suivi.
'Traitement des devis en attente de signature'
This commit is contained in:
107
src/Command/MailCommand.php
Normal file
107
src/Command/MailCommand.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use App\Entity\Devis;
|
||||
use App\Repository\ProductRepository;
|
||||
use App\Repository\OptionsRepository;
|
||||
use App\Service\Mailer\Mailer;
|
||||
use App\Service\Signature\Client;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
use Symfony\Component\Mime\Part\DataPart;
|
||||
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
|
||||
|
||||
#[AsCommand(
|
||||
name: 'app:mail',
|
||||
description: 'Envoi automatisé des emails de suivi (devis, contrats, relances)',
|
||||
)]
|
||||
class MailCommand extends Command
|
||||
{
|
||||
public function __construct(private readonly KernelInterface $kernel,private readonly UploaderHelper $uploaderHelper,private readonly Client $client,private readonly Mailer $mailer,private readonly EntityManagerInterface $entityManager)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$now = new \DateTime();
|
||||
|
||||
// 1. Devis en attente de signature
|
||||
$io->title('Traitement des devis en attente de signature');
|
||||
$devisWaiting = $this->entityManager->getRepository(Devis::class)->findBy(['state' => 'wait-sign']);
|
||||
foreach ($devisWaiting as $devis) {
|
||||
$createdAt = $devis->getCreateA(); // Date de création
|
||||
|
||||
// On calcule la différence en jours entre aujourd'hui et la date de création
|
||||
if ($createdAt instanceof \DateTimeInterface) {
|
||||
$diff = $createdAt->diff($now)->days;
|
||||
|
||||
// On ne traite que si le devis a au moins 3 jours d'ancienneté
|
||||
if ($diff >= 3) {
|
||||
$customer = $devis->getCustomer();
|
||||
$fullName = $customer->getName() . " " . $customer->getSurname();
|
||||
$email = $customer->getEmail();
|
||||
|
||||
$doc = $this->uploaderHelper->asset($devis,'devisFile');
|
||||
$files =[];
|
||||
$files[] = new DataPart(file_get_contents($this->kernel->getProjectDir()."/public".$doc),"Devis N°".$devis->getNum(),"application/pdf");
|
||||
$this->mailer->send(
|
||||
$email,
|
||||
$fullName,
|
||||
"[Reservation Ludikevent] - Vous avez toujours un devis à signer ! - DEVIS N°" . $devis->getNum(),
|
||||
"mails/task/task-nosigned.twig",
|
||||
[
|
||||
'devis' => $devis,
|
||||
'customer' => $customer,
|
||||
'sign' => $this->client->getLinkSign($devis->getSignatureId()),
|
||||
],
|
||||
$files);
|
||||
|
||||
$io->text("Mail envoyé à : $email (Devis " . $devis->getNum() . ", créé il y a $diff jours)");
|
||||
}
|
||||
}
|
||||
}
|
||||
$io->info('Analyse des devis envoyés non signés...');
|
||||
|
||||
// 2. Contrat en attente de signature
|
||||
$io->title('Traitement des contrats en attente de signature');
|
||||
// TODO: Logique de récupération et d'envoi
|
||||
$io->info('Analyse des contrats en attente de signature électronique...');
|
||||
|
||||
// 3. Contrat en attente de paiement acompte
|
||||
$io->title('Traitement des contrats en attente de paiement acompte');
|
||||
// TODO: Logique de récupération et d'envoi
|
||||
$io->info('Vérification des acomptes non reçus...');
|
||||
|
||||
// 4. Contrat en attente de paiement caution
|
||||
$io->title('Traitement des contrats en attente de paiement caution');
|
||||
// TODO: Logique de récupération et d'envoi
|
||||
$io->info('Vérification des dépôts de garantie manquants...');
|
||||
|
||||
// 5. Mail J-3 avant début événement
|
||||
$io->title('Mail J-3 avant début événement');
|
||||
// TODO: Logique de récupération et d'envoi
|
||||
$io->info('Préparation des rappels logistiques (J-3)...');
|
||||
|
||||
// 6. Mail J-1 avant début événement
|
||||
$io->title('Mail J-1 avant début événement');
|
||||
// TODO: Logique de récupération et d'envoi
|
||||
$io->info('Envoi des dernières informations (J-1)...');
|
||||
|
||||
// 7. Mail après événement à +3j (Satisfaction / Facture finale)
|
||||
$io->title('Mail après événement à +3j');
|
||||
// TODO: Logique de récupération et d'envoi
|
||||
$io->info('Envoi des questionnaires de satisfaction et remerciements...');
|
||||
|
||||
$io->success('Toutes les tâches d\'envoi d\'emails ont été traitées.');
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
38
templates/mails/task/task-nosigned.twig
Normal file
38
templates/mails/task/task-nosigned.twig
Normal file
@@ -0,0 +1,38 @@
|
||||
{% extends 'mails/base.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<mj-section background-color="#ffffff" padding="40px 20px" border-radius="20px">
|
||||
<mj-column>
|
||||
{# Affichage des totaux via vos filtres personnalisés #}
|
||||
<mj-text font-size="16px" color="#333333">
|
||||
<strong>Total du devis :</strong> {{ datas.devis|totalQuoto }} €
|
||||
</mj-text>
|
||||
|
||||
<mj-text font-size="16px" color="#333333">
|
||||
<strong>Acompte:</strong> {{ datas.devis|totalQuotoAccompte }} €
|
||||
</mj-text>
|
||||
|
||||
{# Calcul des arrhes de 25% basé sur le montant total #}
|
||||
{# On suppose que totalQuoto renvoie un nombre ou est convertible #}
|
||||
<mj-text font-size="18px" color="#e74c3c" font-weight="bold">
|
||||
Arrhes à régler (25%) : {{ (datas.devis|totalQuoto * 0.25)|number_format(2, ',', ' ') }} €
|
||||
</mj-text>
|
||||
|
||||
<mj-divider border-color="#f4f4f4" />
|
||||
|
||||
<mj-text font-size="14px" color="#555555">
|
||||
Bonjour {{ datas.customer.name }} {{ datas.customer.surname }},
|
||||
</mj-text>
|
||||
|
||||
<mj-text font-size="14px" color="#555555" line-height="20px">
|
||||
Votre devis n°<strong>{{ datas.devis.num }}</strong> est toujours en attente de signature.
|
||||
</mj-text>
|
||||
|
||||
<mj-button background-color="#3498db" color="white" href="{{ datas.sign }}">
|
||||
Voir et signer mon devis
|
||||
</mj-button>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user