From ee8ba6b2df1e46a3e017f9924ec89192acfb62ee Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Tue, 30 Sep 2025 13:26:57 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(artemis/esyweb):=20Ajoute=20la?= =?UTF-8?q?=20gestion=20des=20tutoriels=20ESY-WEB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Crée une page pour lister et gérer les tutoriels ESY-WEB dans Artemis. Ajoute un formulaire pour créer de nouveaux tutoriels. Gère l'upload de fichiers mp4 pour les tutoriels. --- assets/class/ConfirmModal.js | 27 +++ config/packages/vich_uploader.yaml | 7 + docker/php/Dockerfile | 1 + docker/php/custom.ini | 2 + migrations/Version20250930100019.php | 33 ++++ migrations/Version20250930104036.php | 32 +++ .../ApiInterne/RegisterController.php | 39 +++- .../Artemis/EsyWeb/TutoController.php | 64 ++++++ src/Controller/TutoController.php | 31 +++ src/Entity/EsyWebTuto.php | 183 ++++++++++++++++++ src/Form/Artemis/EsyWeb/TutoType.php | 34 ++++ src/Repository/EsyWebTutoRepository.php | 43 ++++ templates/artemis/base.twig | 16 ++ templates/artemis/esyweb/tuto.twig | 41 ++++ templates/artemis/esyweb/tuto_add.twig | 15 ++ 15 files changed, 563 insertions(+), 5 deletions(-) create mode 100644 docker/php/custom.ini create mode 100644 migrations/Version20250930100019.php create mode 100644 migrations/Version20250930104036.php create mode 100644 src/Controller/Artemis/EsyWeb/TutoController.php create mode 100644 src/Controller/TutoController.php create mode 100644 src/Entity/EsyWebTuto.php create mode 100644 src/Form/Artemis/EsyWeb/TutoType.php create mode 100644 src/Repository/EsyWebTutoRepository.php create mode 100644 templates/artemis/esyweb/tuto.twig create mode 100644 templates/artemis/esyweb/tuto_add.twig diff --git a/assets/class/ConfirmModal.js b/assets/class/ConfirmModal.js index 2d4b76b..022d676 100644 --- a/assets/class/ConfirmModal.js +++ b/assets/class/ConfirmModal.js @@ -16,10 +16,37 @@ export class ConfirmModal extends HTMLAnchorElement{ if(element.getAttribute('type') == "delete-email") { this.deleteEmail(modalConfirm,element.getAttribute('href')); } + if(element.getAttribute('type') == "delete-esyweb-tuto") { + this.deleteEsyWebTuto(modalConfirm,element.getAttribute('href')); + } document.body.appendChild(modalConfirm); }) } + deleteEsyWebTuto(modalConfirm,link) { + let message = document.createElement('h2'); + message.innerText = "Confirmer la suppression du tutoriel"; + modalConfirm.querySelector('.confirm-modal-content').appendChild(message); + + let grid = document.createElement('div') + grid.classList = "grid grid-cols-1 gap-4 md:grid-cols-2"; + modalConfirm.querySelector('.confirm-modal-content').appendChild(grid); + + let buttonOk = document.createElement('button'); + buttonOk.classList = "bg-green-600 hover:bg-green-700 text-white px-3 py-1 rounded"; + buttonOk.innerText = "Oui"; + buttonOk.addEventListener('click',()=>{ + modalConfirm.remove() + location.href = link; + }) + + let buttonKo = document.createElement('button'); + buttonKo.classList = "bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded"; + buttonKo.innerText = "Non"; + buttonKo.addEventListener('click',()=>modalConfirm.remove()) + grid.appendChild(buttonOk) + grid.appendChild(buttonKo) + } deleteEmail(modalConfirm,link) { let message = document.createElement('h2'); message.innerText = "Confirmer la suppression de l'email"; diff --git a/config/packages/vich_uploader.yaml b/config/packages/vich_uploader.yaml index 56848e3..96f0562 100644 --- a/config/packages/vich_uploader.yaml +++ b/config/packages/vich_uploader.yaml @@ -57,6 +57,13 @@ vich_uploader: inject_on_load: false delete_on_update: true delete_on_remove: true + tuto: + uri_prefix: /storage/tuto + upload_destination: '%kernel.project_dir%/public/storage/tuto' + namer: Vich\UploaderBundle\Naming\SmartUniqueNamer # Replaced namer + inject_on_load: false + delete_on_update: true + delete_on_remove: true #mappings: # products: # uri_prefix: /images/products diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile index 4254ded..5381ace 100644 --- a/docker/php/Dockerfile +++ b/docker/php/Dockerfile @@ -67,6 +67,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends git \ && apt-get autoremove -y build-essential git \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +COPY ./docker/php/custom.ini /usr/local/etc/php/conf.d/custom.ini RUN echo "zend_extension=xdebug" > /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini RUN echo "xdebug.mode=develop,debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ diff --git a/docker/php/custom.ini b/docker/php/custom.ini new file mode 100644 index 0000000..c0f1eee --- /dev/null +++ b/docker/php/custom.ini @@ -0,0 +1,2 @@ +upload_max_filesize=128M +post_max_size=128M diff --git a/migrations/Version20250930100019.php b/migrations/Version20250930100019.php new file mode 100644 index 0000000..c25f351 --- /dev/null +++ b/migrations/Version20250930100019.php @@ -0,0 +1,33 @@ +addSql('CREATE TABLE esy_web_tuto (id SERIAL NOT NULL, title TEXT NOT NULL, file_name VARCHAR(255) DEFAULT NULL, file_dimensions JSON DEFAULT NULL, file_size VARCHAR(255) DEFAULT NULL, file_mine_type VARCHAR(255) DEFAULT NULL, file_original_name VARCHAR(255) DEFAULT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('COMMENT ON COLUMN esy_web_tuto.update_at IS \'(DC2Type:datetime_immutable)\''); + } + + 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('DROP TABLE esy_web_tuto'); + } +} diff --git a/migrations/Version20250930104036.php b/migrations/Version20250930104036.php new file mode 100644 index 0000000..a179a7b --- /dev/null +++ b/migrations/Version20250930104036.php @@ -0,0 +1,32 @@ +addSql('ALTER TABLE esy_web_tuto ADD pos INT NOT 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 esy_web_tuto DROP pos'); + } +} diff --git a/src/Controller/ApiInterne/RegisterController.php b/src/Controller/ApiInterne/RegisterController.php index 15f6de4..0e96826 100644 --- a/src/Controller/ApiInterne/RegisterController.php +++ b/src/Controller/ApiInterne/RegisterController.php @@ -3,18 +3,23 @@ namespace App\Controller\ApiInterne; use App\Entity\Compute; +use App\Entity\CustomerAdvertPayment; +use App\Entity\CustomerAdvertPaymentLine; use App\Entity\CustomerAdvertPaymentRegister; use App\Repository\CustomerAdvertPaymentRepository; +use App\Service\Customer\CreateAvisEvent; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; class RegisterController extends AbstractController { #[Route(path: '/api-interne/intranet/customer/register',name: 'api-interne-intranet-customer-register')] - public function customerRegisterPayment(Request $request,CustomerAdvertPaymentRepository $customerAdvertPaymentRepository): Response { + public function customerRegisterPayment(EventDispatcherInterface $eventDispatcher,EntityManagerInterface $entityManager,Request $request,CustomerAdvertPaymentRepository $customerAdvertPaymentRepository): Response { $content = $request->getContent(); $content = json_decode($content); $format = []; @@ -33,15 +38,39 @@ class RegisterController extends AbstractController $advertRegister->setAmount(floatval($format['amount'])); $advertRegister->setNumeroRemise($format['num_cheque']); $advertRegister->setChequeNum($format['num_cheque']); + $entityManager->persist($advertRegister); - //if complete paiement generated fac - if(floatval($format['num_cheque']) < $total) { - //send mail with no completed - $diff = $total - floatval($format['amount']); + $diff = $total - floatval($format['amount']); + if($diff >0){ + $t = new \DateTimeImmutable(); + $num = 'A-' . $t->format('Y/m') . '/' . sprintf('%05d', $entityManager->getRepository(CustomerAdvertPayment::class)->count() + 1); + $diffAdvert = new CustomerAdvertPayment(); + $diffAdvert->setCustomer($advertRegister->getAdvert()->getCustomer()); + $diffAdvert->setDevis($advertRegister->getAdvert()->getDevis()); + $diffAdvert->setUpdateAt(\DateTimeImmutable::createFromFormat('Y-m-d', $format['date'])); + $diffAdvert->setCreateAt(\DateTimeImmutable::createFromFormat('Y-m-d', $format['date'])); + $diffAdvert->setNumAvis($num); + $diffAdvert->setState('created'); + $entityManager->persist($diffAdvert); + $diffAdvertLine = new CustomerAdvertPaymentLine(); + $diffAdvertLine->setPos(0); + $diffAdvertLine->setTva(1.20); + $diffAdvertLine->setName("Différence de paiement ".$advertRegister->getAdvert()->getNumAvis()); + $diffAdvertLine->setPriceHt($diff / 1.20); + $diffAdvertLine->setContent(""); + $entityManager->persist($diffAdvertLine); + $diffAdvert->addCustomerAdvertPaymentLine($diffAdvertLine); + $entityManager->persist($diffAdvert); + $entityManager->flush(); + $event = new CreateAvisEvent($diffAdvert, true); + $eventDispatcher->dispatch($event); + + return $this->json([]); } else { dd("completed"); } + //if no completed // generated confirmation payement // generate new advert payment diff --git a/src/Controller/Artemis/EsyWeb/TutoController.php b/src/Controller/Artemis/EsyWeb/TutoController.php new file mode 100644 index 0000000..d98ecb0 --- /dev/null +++ b/src/Controller/Artemis/EsyWeb/TutoController.php @@ -0,0 +1,64 @@ +setPos($esyWebTutoRepository->count()); + $tuto->setUpdateAt(new \DateTimeImmutable()); + $form = $this->createForm(TutoType::class,$tuto); + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + + $entityManager->persist($tuto); + $entityManager->flush(); + + $loggerService->log("SUCCESS","Crée un tutoriel"); + $this->addFlash("success","Tutoriel crée un tutoriel"); + return $this->redirectToRoute('artemis_esyweb_tuto'); + } + return $this->render('artemis/esyweb/tuto_add.twig',[ + 'form' => $form->createView(), + ]); + } + #[Route(path: '/artemis/esyweb/tuto', name: 'artemis_esyweb_tuto', methods: ['GET', 'POST'])] + public function tutos(KernelInterface $kernel,Request $request,UploaderHelper $uploaderHelper,LoggerService $loggerService,EsyWebTutoRepository $esyWebTutoRepository,EntityManagerInterface $entityManager) + { + + if($request->query->has('idDelete')) { + $ndd = $esyWebTutoRepository->find($request->query->get('idDelete')); + $entityManager->remove($ndd); + $entityManager->flush(); + $loggerService->log("DELETE","Suppression d'un tutoriel"); + $this->addFlash("success","Tutoriel bien supprimer"); + return $this->redirectToRoute('artemis_esyweb_tuto'); + } + + if($request->query->has('idView')) { + $ndd = $esyWebTutoRepository->find($request->query->get('idView')); + $path = $uploaderHelper->asset($ndd,'file'); + $response = new BinaryFileResponse($kernel->getProjectDir()."/public".$path); + return $response; + } + + return $this->render('artemis/esyweb/tuto.twig',[ + 'tutos' => $esyWebTutoRepository->findAll(), + ]); + } +} diff --git a/src/Controller/TutoController.php b/src/Controller/TutoController.php new file mode 100644 index 0000000..95f10a4 --- /dev/null +++ b/src/Controller/TutoController.php @@ -0,0 +1,31 @@ +id; + } + + public function getTitle(): ?string + { + return $this->title; + } + + public function setTitle(string $title): static + { + $this->title = $title; + + return $this; + } + + /** + * @return string|null + */ + public function getFileSize(): ?string + { + return $this->fileSize; + } + + /** + * @return string|null + */ + public function getFileOriginalName(): ?string + { + return $this->fileOriginalName; + } + + /** + * @return \DateTimeImmutable|null + */ + public function getUpdateAt(): ?\DateTimeImmutable + { + return $this->updateAt; + } + + /** + * @return string|null + */ + public function getFileName(): ?string + { + return $this->fileName; + } + + /** + * @return string|null + */ + public function getFileMineType(): ?string + { + return $this->fileMineType; + } + + /** + * @return array|null + */ + public function getFileDimensions(): ?array + { + return $this->fileDimensions; + } + + /** + * @return File|null + */ + public function getFile(): ?File + { + return $this->file; + } + + /** + * @param File|null $file + */ + public function setFile(?File $file): void + { + $this->file = $file; + } + + /** + * @param \DateTimeImmutable|null $updateAt + */ + public function setUpdateAt(?\DateTimeImmutable $updateAt): void + { + $this->updateAt = $updateAt; + } + + /** + * @param array|null $fileDimensions + */ + public function setFileDimensions(?array $fileDimensions): void + { + $this->fileDimensions = $fileDimensions; + } + + /** + * @param string|null $fileMineType + */ + public function setFileMineType(?string $fileMineType): void + { + $this->fileMineType = $fileMineType; + } + + /** + * @param string|null $fileName + */ + public function setFileName(?string $fileName): void + { + $this->fileName = $fileName; + } + + /** + * @param string|null $fileSize + */ + public function setFileSize(?string $fileSize): void + { + $this->fileSize = $fileSize; + } + + /** + * @param string|null $fileOriginalName + */ + public function setFileOriginalName(?string $fileOriginalName): void + { + $this->fileOriginalName = $fileOriginalName; + } + + public function getPos(): ?int + { + return $this->pos; + } + + public function setPos(int $pos): static + { + $this->pos = $pos; + + return $this; + } +} diff --git a/src/Form/Artemis/EsyWeb/TutoType.php b/src/Form/Artemis/EsyWeb/TutoType.php new file mode 100644 index 0000000..a556db1 --- /dev/null +++ b/src/Form/Artemis/EsyWeb/TutoType.php @@ -0,0 +1,34 @@ +add('title',TextType::class,[ + 'label' => 'Titre du tutoriels', + 'required' => true, + ]) + ->add('file',FileType::class,[ + 'label' => 'Fichier du tutoriel (mp4)', + 'attr' => [ + 'accept' => 'video/mp4' + ] + ]); + + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('data_class',EsyWebTuto::class); + } +} diff --git a/src/Repository/EsyWebTutoRepository.php b/src/Repository/EsyWebTutoRepository.php new file mode 100644 index 0000000..e7f4caa --- /dev/null +++ b/src/Repository/EsyWebTutoRepository.php @@ -0,0 +1,43 @@ + + */ +class EsyWebTutoRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, EsyWebTuto::class); + } + + // /** + // * @return EsyWebTuto[] Returns an array of EsyWebTuto objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('e') + // ->andWhere('e.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('e.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?EsyWebTuto + // { + // return $this->createQueryBuilder('e') + // ->andWhere('e.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/templates/artemis/base.twig b/templates/artemis/base.twig index 9c3f391..f61fe53 100644 --- a/templates/artemis/base.twig +++ b/templates/artemis/base.twig @@ -65,6 +65,22 @@ Tableau de bord +
  • + + +
  • + + {{ form_end(form) }} + +{% endblock %}