```
✨ feat(AG/Admin): Ajoute la signature Docuseal pour l'AG et la gestion des PDFs signés.
```
This commit is contained in:
2
.env
2
.env
@@ -51,7 +51,7 @@ PATH_URL=https://esyweb.local
|
|||||||
STRIPE_PK=pk_test_51SUA22173W4aeFB1nO6oFfDZ12HOTffDKtCshhZ8rkUg6kUO2ZaQC0tK72rhE79Tr8treeHX9KMcZtvcQZ0X8VSm00Q6GQ365V
|
STRIPE_PK=pk_test_51SUA22173W4aeFB1nO6oFfDZ12HOTffDKtCshhZ8rkUg6kUO2ZaQC0tK72rhE79Tr8treeHX9KMcZtvcQZ0X8VSm00Q6GQ365V
|
||||||
STRIPE_SK=sk_test_51SUA22173W4aeFB16EB2LxGI0hNvNJzFshDI98zRImWBIhSfzqOGAz5TlPxSpUWbj3x4COm6kmSsaal9FpQR1A7M0022DvjbbR
|
STRIPE_SK=sk_test_51SUA22173W4aeFB16EB2LxGI0hNvNJzFshDI98zRImWBIhSfzqOGAz5TlPxSpUWbj3x4COm6kmSsaal9FpQR1A7M0022DvjbbR
|
||||||
STRIPE_WEBHOOKS_SIGN=whsec_0DOZJAwgMwkcHl2RWXI8h8YItj9q7v3A
|
STRIPE_WEBHOOKS_SIGN=whsec_0DOZJAwgMwkcHl2RWXI8h8YItj9q7v3A
|
||||||
DEV_URL=https://f584469e204f.ngrok-free.app
|
DEV_URL=https://265fcc9dd2a6.ngrok-free.app
|
||||||
VAPID_PK=DsOg7jToRSD-VpNSV1Gt3YAhSwz4l-nqeu7yFvzbSxg
|
VAPID_PK=DsOg7jToRSD-VpNSV1Gt3YAhSwz4l-nqeu7yFvzbSxg
|
||||||
VAPID_PC=BKz0kdcsG6kk9KxciPpkfP8kEDAd408inZecij5kBDbQ1ZGZSNwS4KZ8FerC28LFXvgSqpDXtor3ePo0zBCdNqo
|
VAPID_PC=BKz0kdcsG6kk9KxciPpkfP8kEDAd408inZecij5kBDbQ1ZGZSNwS4KZ8FerC28LFXvgSqpDXtor3ePo0zBCdNqo
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"doctrine/doctrine-bundle": "^2.18.1",
|
"doctrine/doctrine-bundle": "^2.18.1",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.6.0",
|
"doctrine/doctrine-migrations-bundle": "^3.6.0",
|
||||||
"doctrine/orm": "^3.5.7",
|
"doctrine/orm": "^3.5.7",
|
||||||
|
"docusealco/docuseal-php": "^1.0",
|
||||||
"endroid/qr-code": ">=6.0.9",
|
"endroid/qr-code": ">=6.0.9",
|
||||||
"exbil/mailcow-php-api": ">=0.14.2",
|
"exbil/mailcow-php-api": ">=0.14.2",
|
||||||
"fpdf/fpdf": ">=1.86",
|
"fpdf/fpdf": ">=1.86",
|
||||||
|
|||||||
38
composer.lock
generated
38
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "64d249aa5dd90b9e31a7e0f42b311e18",
|
"content-hash": "d9f711e9feb3143e77672af962c889c8",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "async-aws/core",
|
"name": "async-aws/core",
|
||||||
@@ -2026,6 +2026,42 @@
|
|||||||
},
|
},
|
||||||
"time": "2025-10-26T09:35:14+00:00"
|
"time": "2025-10-26T09:35:14+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "docusealco/docuseal-php",
|
||||||
|
"version": "1.0.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/docusealco/docuseal-php.git",
|
||||||
|
"reference": "f12a490e95bdb13ef61f46b72dffcdc646d8b0a4"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/docusealco/docuseal-php/zipball/f12a490e95bdb13ef61f46b72dffcdc646d8b0a4",
|
||||||
|
"reference": "f12a490e95bdb13ef61f46b72dffcdc646d8b0a4",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Docuseal\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "DocuSeal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP bindings for DocuSeal API",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/docusealco/docuseal-php/issues",
|
||||||
|
"source": "https://github.com/docusealco/docuseal-php/tree/1.0.5"
|
||||||
|
},
|
||||||
|
"time": "2025-09-14T21:27:12+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "egulias/email-validator",
|
"name": "egulias/email-validator",
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
|
|||||||
32
migrations/Version20251123175729.php
Normal file
32
migrations/Version20251123175729.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20251123175729 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE ag_main ADD is_signed BOOLEAN DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE SCHEMA public');
|
||||||
|
$this->addSql('ALTER TABLE ag_main DROP is_signed');
|
||||||
|
}
|
||||||
|
}
|
||||||
32
migrations/Version20251123180010.php
Normal file
32
migrations/Version20251123180010.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20251123180010 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE ag_main ADD submiter_id VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE SCHEMA public');
|
||||||
|
$this->addSql('ALTER TABLE ag_main DROP submiter_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,6 +34,7 @@ use Psr\EventDispatcher\EventDispatcherInterface;
|
|||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
@@ -240,16 +241,62 @@ class AdminController extends AbstractController
|
|||||||
#[Route(path: '/admin/ag', name: 'admin_ag', options: ['sitemap' => false], methods: ['GET'])]
|
#[Route(path: '/admin/ag', name: 'admin_ag', options: ['sitemap' => false], methods: ['GET'])]
|
||||||
public function adminAg(UploaderHelper $uploaderHelper,KernelInterface $kernel,EntityManagerInterface $entityManager,Request $request,MainRepository $mainRepository): Response
|
public function adminAg(UploaderHelper $uploaderHelper,KernelInterface $kernel,EntityManagerInterface $entityManager,Request $request,MainRepository $mainRepository): Response
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if($request->query->has('idValidateSign')) {
|
||||||
|
/** @var Main $main */
|
||||||
|
$main = $mainRepository->find($request->query->get('idValidateSign'));
|
||||||
|
$docuseal = new \Docuseal\Api('pgAU116mCFmeF7WQSezHqxtZW8V1fgo31u5d2FXoaKe', 'https://signature.esy-web.dev/api');
|
||||||
|
$sub = $docuseal->getSubmitter($main->getSubmiterId());
|
||||||
|
$link = $sub['documents'][0]['url'];
|
||||||
|
$content = file_get_contents($link);
|
||||||
|
$fileName = 'ag_sign_ecosplay_' . $main->getAgDateAt()->format('Ymd') . '.pdf';
|
||||||
|
$tempFilePath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $fileName;
|
||||||
|
file_put_contents($tempFilePath, $content);
|
||||||
|
$file = new UploadedFile($tempFilePath,$fileName,"application/pdf",0,true);
|
||||||
|
$main->setAg($file);
|
||||||
|
$main->setUpdateAt(new \DateTimeImmutable());
|
||||||
|
$main->setIsSigned(true);
|
||||||
|
$entityManager->persist($main);
|
||||||
|
$entityManager->flush();
|
||||||
|
return $this->redirectToRoute('admin_ag');
|
||||||
|
}
|
||||||
if($request->query->has('idSign')) {
|
if($request->query->has('idSign')) {
|
||||||
/** @var Main $main */
|
/** @var Main $main */
|
||||||
$main = $mainRepository->find($request->query->get('id'));
|
$main = $mainRepository->find($request->query->get('id'));
|
||||||
$url = $uploaderHelper->asset($main,'ag');
|
$url = $uploaderHelper->asset($main,'ag');
|
||||||
|
|
||||||
if($_ENV['APP_ENV'] == "prod")
|
if($_ENV['APP_ENV'] == "prod") {
|
||||||
$url = $request->getContentTypeFormat().$url;
|
$url = $request->getContentTypeFormat() . $url;
|
||||||
else
|
$urlRoot = $request->getContentTypeFormat();
|
||||||
$url = $_ENV['DEV_URL'].$url;
|
} else {
|
||||||
dd($url);
|
$url = $_ENV['DEV_URL'] . $url;
|
||||||
|
$urlRoot = $_ENV['DEV_URL'];
|
||||||
|
}
|
||||||
|
$docuseal = new \Docuseal\Api('pgAU116mCFmeF7WQSezHqxtZW8V1fgo31u5d2FXoaKe', 'https://signature.esy-web.dev/api');
|
||||||
|
$content = $docuseal->createSubmissionFromPdf([
|
||||||
|
'name' => 'AG E-COSPLAY '.$main->getAgDateAt()->format('d/m/Y'),
|
||||||
|
'documents' => [
|
||||||
|
[
|
||||||
|
'name' => 'ag-ecosplay-'.$main->getAgDateAt()->format('d-m-Y'),
|
||||||
|
'file' => $url
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'completed_redirect_url' => $urlRoot.$this->generateUrl('admin_ag',['idValidateSign'=>$main->getId()]),
|
||||||
|
'submitters' => [
|
||||||
|
[
|
||||||
|
'role' => 'First Party',
|
||||||
|
'email' => 'contact@e-cosplay.fr'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
$slug = $content['submitters'][0]['id'];
|
||||||
|
$main->setSubmiterId($slug);
|
||||||
|
$entityManager->persist($main);
|
||||||
|
$entityManager->flush();
|
||||||
|
$path = $content['submitters'][0]['embed_src'];
|
||||||
|
$r = new RedirectResponse($path);
|
||||||
|
$r->setStatusCode(302);
|
||||||
|
return $r;
|
||||||
}
|
}
|
||||||
if($request->query->has('idGenerate')) {
|
if($request->query->has('idGenerate')) {
|
||||||
/** @var Main $main */
|
/** @var Main $main */
|
||||||
|
|||||||
@@ -82,6 +82,12 @@ class Main
|
|||||||
private ?string $agOriginalName = null;
|
private ?string $agOriginalName = null;
|
||||||
#[ORM\Column(nullable: true)]
|
#[ORM\Column(nullable: true)]
|
||||||
private ?\DateTimeImmutable $updateAt;
|
private ?\DateTimeImmutable $updateAt;
|
||||||
|
|
||||||
|
#[ORM\Column(nullable: true)]
|
||||||
|
private ?bool $isSigned = null;
|
||||||
|
|
||||||
|
#[ORM\Column(nullable: true)]
|
||||||
|
private ?string $submiterId = null;
|
||||||
/**
|
/**
|
||||||
* @return File|null
|
* @return File|null
|
||||||
*/
|
*/
|
||||||
@@ -411,4 +417,28 @@ class Main
|
|||||||
{
|
{
|
||||||
$this->agSize = $agSize;
|
$this->agSize = $agSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isSigned(): ?bool
|
||||||
|
{
|
||||||
|
return $this->isSigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setIsSigned(?bool $isSigned): static
|
||||||
|
{
|
||||||
|
$this->isSigned = $isSigned;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubmiterId(): ?string
|
||||||
|
{
|
||||||
|
return $this->submiterId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSubmiterId(string $submiterId): static
|
||||||
|
{
|
||||||
|
$this->submiterId = $submiterId;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,12 +75,21 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-600 flex space-x-3">
|
{% if ag.isSigned == true %}
|
||||||
<a href="{{ path('admin_ag',{id:ag.id,idSign:true}) }}"
|
<div class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-600 flex space-x-3">
|
||||||
class="inline-flex items-center px-3 py-1.5 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-cyan-600 hover:bg-cyan-700 dark:bg-cyan-500 dark:hover:bg-cyan-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
<a download="ag_ecosplay_{{ ag.agDateAt|date('d/m/Y') }}.pdf" href="{{ vich_uploader_asset(ag,'ag') }}"
|
||||||
Signature le pdf
|
class="inline-flex items-center px-3 py-1.5 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-cyan-600 hover:bg-cyan-700 dark:bg-cyan-500 dark:hover:bg-cyan-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||||
</a>
|
Télécharger le pdf
|
||||||
</div>
|
</a>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-600 flex space-x-3">
|
||||||
|
<a href="{{ path('admin_ag',{id:ag.id,idSign:true}) }}"
|
||||||
|
class="inline-flex items-center px-3 py-1.5 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-cyan-600 hover:bg-cyan-700 dark:bg-cyan-500 dark:hover:bg-cyan-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||||
|
Signature le pdf
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
Reference in New Issue
Block a user