✨ 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:
@@ -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 }}"
|
||||
|
||||
60
src/Command/EventTodayCommand.php
Normal file
60
src/Command/EventTodayCommand.php
Normal 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;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
69
templates/mails/event-today.twig
Normal file
69
templates/mails/event-today.twig
Normal 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 %}
|
||||
Reference in New Issue
Block a user