```
✨ feat(Product.php): Ajoute la relation avec ProductReserve. ✨ feat(DevisSubscriber.php): Crée un subscriber pour l'envoi de devis. ✨ feat(Devis.php): Ajoute la relation avec ProductReserve. ✨ feat: Crée le template de mail pour la notification de signature. ✨ feat(DevisSend.php): Crée l'événement DevisSend. ✨ feat(Customer.php): Ajoute la relation avec ProductReserve. 🐛 fix(SignatureController.php): Corrige la gestion de la signature complétée. ✨ feat(DevisController.php): Ajoute la relance de signature et pagination. ✨ feat: Crée le template de mail pour l'envoi du devis à signer. ✨ feat: Crée le template de mail pour la confirmation de signature. ✨ feat(Client.php): Gère la création et le suivi de la signature DocuSeal. ✨ feat(DevisPdfService.php): Intègre les champs Docuseal. ✨ feat(list.twig): Affiche la liste des devis avec actions et statuts. ✨ feat: Crée la page de succès de signature. ✨ feat(StripeExtension.php): Ajoute le filtre totalQuoto pour calculer le total HT. ```
This commit is contained in:
@@ -4,18 +4,25 @@ namespace App\Controller;
|
||||
|
||||
use App\Entity\Account;
|
||||
use App\Entity\AccountResetPasswordRequest;
|
||||
use App\Entity\Devis;
|
||||
use App\Entity\ProductReserve;
|
||||
use App\Form\RequestPasswordConfirmType;
|
||||
use App\Form\RequestPasswordRequestType;
|
||||
use App\Logger\AppLogger;
|
||||
use App\Repository\DevisRepository;
|
||||
use App\Service\Mailer\Mailer;
|
||||
use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent;
|
||||
use App\Service\ResetPassword\Event\ResetPasswordEvent;
|
||||
use App\Service\Signature\Client;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Mime\Part\DataPart;
|
||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
@@ -26,9 +33,104 @@ class SignatureController extends AbstractController
|
||||
{
|
||||
|
||||
#[Route('/signature/complete', name: 'app_sign_complete')]
|
||||
public function appSignComplete()
|
||||
{
|
||||
public function appSignComplete(
|
||||
Client $client,
|
||||
DevisRepository $devisRepository,
|
||||
EntityManagerInterface $entityManager,
|
||||
Request $request,
|
||||
Mailer $mailer,
|
||||
): Response {
|
||||
if ($request->get('type') === "devis") {
|
||||
$devis = $devisRepository->find($request->get('id'));
|
||||
|
||||
if (!$devis) {
|
||||
throw $this->createNotFoundException("Devis introuvable.");
|
||||
}
|
||||
|
||||
// On évite de retraiter un devis déjà marqué comme signé
|
||||
if ($devis->getState() === 'signed') {
|
||||
return $this->render('sign/sign_success.twig', ['devis' => $devis]);
|
||||
}
|
||||
|
||||
$submiter = $client->getSubmiter($devis->getSignatureId());
|
||||
$submission = $client->getSubmition($submiter['submission_id']);
|
||||
|
||||
if ($submission['status'] === "completed") {
|
||||
$devis->setState("signed");
|
||||
|
||||
$auditUrl = $submission['audit_log_url'];
|
||||
$signedDocUrl = $submission['documents'][0]['url'];
|
||||
|
||||
try {
|
||||
// 1. Gestion du PDF SIGNÉ
|
||||
$tmpSigned = sys_get_temp_dir() . '/sign_' . uniqid() . '.pdf';
|
||||
$signedContent = file_get_contents($signedDocUrl);
|
||||
file_put_contents($tmpSigned, $signedContent);
|
||||
|
||||
// On utilise UploadedFile pour simuler un upload propre pour VichUploader
|
||||
$devis->setDevisSignFile(new UploadedFile($tmpSigned, "sign-" . $devis->getNum() . ".pdf", "application/pdf", null, true));
|
||||
|
||||
// 2. Gestion de l'AUDIT LOG
|
||||
$tmpAudit = sys_get_temp_dir() . '/audit_' . uniqid() . '.pdf';
|
||||
$auditContent = file_get_contents($auditUrl);
|
||||
file_put_contents($tmpAudit, $auditContent);
|
||||
|
||||
$devis->setDevisAuditFile(new UploadedFile($tmpAudit, "audit-" . $devis->getNum() . ".pdf", "application/pdf", null, true));
|
||||
|
||||
// 3. Préparation des pièces jointes pour le mail (Le PDF signé est le plus important)
|
||||
$attachments = [
|
||||
new DataPart($signedContent, "Devis-" . $devis->getNum() . "-Signe.pdf", "application/pdf"),
|
||||
new DataPart($auditContent, "Certificat-Signature-" . $devis->getNum() . ".pdf", "application/pdf"),
|
||||
];
|
||||
|
||||
|
||||
// 4. Sauvegarde en base de données
|
||||
$devis->setUpdateAt(new \DateTimeImmutable());
|
||||
|
||||
foreach ($devis->getDevisLines() as $line) {
|
||||
$product = $line->getProduct();
|
||||
|
||||
$productReserve = new ProductReserve();
|
||||
$productReserve->setProduct($product);
|
||||
$productReserve->setCustomer($devis->getCustomer());
|
||||
$productReserve->setStartAt($line->getStartAt());
|
||||
$productReserve->setEndAt($line->getEndAt());
|
||||
$productReserve->setDevis($devis);
|
||||
$entityManager->persist($productReserve);
|
||||
}
|
||||
$entityManager->persist($devis);
|
||||
$entityManager->flush();
|
||||
|
||||
// 5. Envoi du mail de confirmation avec le récapitulatif
|
||||
$mailer->send(
|
||||
$devis->getCustomer()->getEmail(),
|
||||
$devis->getCustomer()->getName() . " " . $devis->getCustomer()->getSurname(),
|
||||
"[Ludikevent] Confirmation de signature - Devis " . $devis->getNum(),
|
||||
"mails/sign/signed.twig",
|
||||
[
|
||||
'devis' => $devis // Correction ici : passage de l'objet, pas d'un string
|
||||
],
|
||||
$attachments
|
||||
);
|
||||
$mailer->send(
|
||||
"contact@ludikevent.fr",
|
||||
"Ludikevent",
|
||||
"[Intranet Ludikevent] Confirmation signature d'un client pour - Devis " . $devis->getNum(),
|
||||
"mails/sign/signed_notification.twig",
|
||||
[
|
||||
'devis' => $devis // Correction ici : passage de l'objet, pas d'un string
|
||||
],
|
||||
$attachments
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
return new Response("Erreur lors de la récupération ou de l'envoi des documents : " . $e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render('sign/sign_success.twig', [
|
||||
'devis' => $devis ?? null
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user