feat(mail/cron): Ajoute rapport quotidien des signatures et commande cron

Ajoute un rapport quotidien des signatures de devis acceptés/refusés, envoyé par email, et une commande cron pour l'automatiser.
This commit is contained in:
Serreau Jovann
2025-10-15 14:52:13 +02:00
parent ce4b6898bb
commit 21b4aeea63
6 changed files with 167 additions and 2 deletions

View File

@@ -210,6 +210,7 @@
hour: "*"
job: "sh {{ path }}/script/demande/run.sh"
user: root
- name: "Cron Task purge customer delete"
cron:
name: "Mainframe - Purge customer"
@@ -240,7 +241,14 @@
user: "root"
job: "php {{ path }}/bin/console mainframe:cron:sync"
state: present
- name: "Cron Task sync"
ansible.builtin.cron:
name: "Mainframe - Event Today"
minute: "50"
hour: "23"
user: "root"
job: "php {{ path }}/bin/console mainframe:event:today"
state: present
- name: Set correct permissions for Symfony cache and logs directories
ansible.builtin.file:
path: "{{ item }}"

View File

@@ -0,0 +1,60 @@
<?php
namespace App\Command;
use App\Entity\CustomerDevis;
use App\Entity\SignEvent;
use App\Repository\CustomerDevisRepository;
use App\Repository\SignEventRepository;
use App\Service\Docuseal\SignClient;
use App\Service\Mailer\Mailer;
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;
#[AsCommand(name: 'mainframe:event:today')]
class EventTodayCommand extends Command
{
public function __construct(
private readonly Mailer $mailer,
private readonly SignEventRepository $signEventRepository,
private readonly CustomerDevisRepository $customerDevisRepository,
private readonly SignClient $signClient,
?string $name = null)
{
parent::__construct($name);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title("Check today event");
$signEventList = [];
$signEvent = $this->signEventRepository->today();
/** @var SignEvent $event */
foreach ($signEvent as $event) {
$submiter = $this->signClient->getSubmiter($event->getSubmiterEvent());
$medata = $submiter['metadata'];
if($medata['type'] == "devis") {
$devis = $this->customerDevisRepository->find($medata['id']);
if($devis instanceof CustomerDevis && ($devis->getState() == "accepted" or str_contains($devis->getState(),"declined"))) {
$signEventList[$devis->getId()] = [
'devis' => $devis->getNumDevis(),
'customer' => $devis->getCustomer()->getRaisonSocial(),
'status' => $devis->getState(),
];
}
}
}
$this->mailer->sendMulti(['jovann@siteconseil.fr','legrand@siteconseil.fr'],"[Mainframe] - Evénement de la journée","mails/event-today.twig",[
'signEvent' => $signEventList,
]);
return Command::SUCCESS;
}
}

View File

@@ -66,7 +66,7 @@ class SignController extends AbstractController
$submittersId = $content->submission_id;
$sign = new SignEvent();
$sign->setSubmiterEvent($submittersId);
$sign->setSubmiterEvent($content->meta_id);
$sign->setState($event_type);
$sign->setActionAt(\DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s.v\Z',$timestamp));
$entityManager->persist($sign);

View File

@@ -40,4 +40,27 @@ class SignEventRepository extends ServiceEntityRepository
// ->getOneOrNullResult()
// ;
// }
public function today(): array
{
// 1. Crée un objet DateTime représentant l'heure actuelle
$now = new \DateTime('now');
// 2. Clone l'objet et le met à 00:00:00 pour la limite de début
$startOfDay = clone $now;
$startOfDay->setTime(0, 0, 0);
// 3. Clone l'objet et le met à 23:59:59 pour la limite de fin
$endOfDay = clone $now;
$endOfDay->setTime(23, 59, 59);
// 4. Exécute la requête DQL
return $this->createQueryBuilder('signEvent')
->andWhere('signEvent.actionAt BETWEEN :start AND :end')
// Passer les objets DateTime directement à setParameter
->setParameter('start', $startOfDay)
->setParameter('end', $endOfDay)
->getQuery()
->getResult();
}
}

View File

@@ -118,4 +118,9 @@ class SignClient
$submissionData = $this->docuseal->getSubmission($submittersId);
return "https://signature.esy-web.dev/s/" . $submissionData['slug'];
}
public function getSubmiter(?int $getSubmiterEvent)
{
return $this->docuseal->getSubmitter($getSubmiterEvent);
}
}

View File

@@ -0,0 +1,69 @@
{% extends 'mails/base.twig' %}
{% block content %}
<mj-text font-size="20px" line-height="28px" font-weight="bold" color="#333333">
Rapport des Signatures du Jour ({{ "now"|date("d/m/Y") }})
</mj-text>
{% if datas.signEvent is empty %}
<mj-section background-color="#f5f5f5">
<mj-column>
<mj-text font-size="16px" line-height="24px" color="#555555">
Aucun événement de signature n'a été enregistré aujourd'hui.
</mj-text>
</mj-column>
</mj-section>
{% else %}
<mj-section background-color="#ffffff" padding-top="20px">
<mj-column>
<mj-text font-size="16px" line-height="24px" font-weight="bold" color="#333333" padding-bottom="10px">
{{ datas.signEvent|length }} Événement(s) de Signature
</mj-text>
</mj-column>
</mj-section>
{# Boucle sur la liste des événements #}
{% for event in datas.signEvent %}
<mj-section background-color="#ffffff" padding-top="10px" padding-bottom="10px">
{# Colonne pour le Devis et l'Heure #}
<mj-column width="50%">
<mj-text font-size="14px" line-height="20px" color="#333333">
<span style="font-weight: bold;">Devis N°:</span> {{ event.devis }}
</mj-text>
</mj-column>
{# Colonne pour le Statut #}
<mj-column width="50%">
<mj-text font-size="14px" line-height="20px" color="#333333" align="right">
<span style="font-weight: bold;">Statut:</span>
<span style="color: {% if event.status == 'accepted' %}#10B981{% else %}#F59E0B{% endif %}; font-weight: bold;">
{{ event.status }}
</span>
</mj-text>
</mj-column>
{# Nom du client sur une nouvelle section pour plus d'espace #}
<mj-column width="100%">
<mj-text font-size="14px" line-height="20px" color="#333333" padding-top="5px">
<span style="font-weight: bold;">Client:</span> {{ event.customer }}
</mj-text>
</mj-column>
</mj-section>
{# Séparateur entre les événements #}
{% if not loop.last %}
<mj-divider border-width="1px" border-style="dotted" border-color="#dddddd" padding="0 25px"></mj-divider>
{% endif %}
{% endfor %}
{% endif %}
<mj-text font-size="16px" line-height="24px" padding-top="20px">
Cordialement,<br/><br/>
L'équipe SARL SITECONSEIL
</mj-text>
{% endblock %}