diff --git a/migrations/Version20260128082804.php b/migrations/Version20260128082804.php new file mode 100644 index 0000000..e8c20a9 --- /dev/null +++ b/migrations/Version20260128082804.php @@ -0,0 +1,32 @@ +addSql('ALTER TABLE formules ADD is_publish 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 formules DROP is_publish'); + } +} diff --git a/migrations/Version20260128083151.php b/migrations/Version20260128083151.php new file mode 100644 index 0000000..b032442 --- /dev/null +++ b/migrations/Version20260128083151.php @@ -0,0 +1,32 @@ +addSql('ALTER TABLE formules ADD description TEXT 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 formules DROP description'); + } +} diff --git a/src/Controller/Dashboard/FormulesController.php b/src/Controller/Dashboard/FormulesController.php index 7d71b25..18fa8ba 100644 --- a/src/Controller/Dashboard/FormulesController.php +++ b/src/Controller/Dashboard/FormulesController.php @@ -38,19 +38,57 @@ class FormulesController extends AbstractController 'formules' => $paginator->paginate($formulesRepository->findBy([],['id'=>'asc']), $request->query->getInt('page', 1), 10), ]); } - #[Route(path: '/crm/formules/add', name: 'app_crm_formules_add', methods: ['GET'])] - public function formulesAdd(PaginatorInterface $paginator,AppLogger $appLogger,Request $request,FormulesRepository $formulesRepository): Response + #[Route(path: '/crm/formules/delete/{id}', name: 'app_crm_formules_delete', methods: ['POST', 'GET'])] + public function formulesDelete( + ?Formules $formules, + AppLogger $appLogger, + EntityManagerInterface $entityManager, + Request $request + ): Response { + // 1. Vérification de l'existence de la formule + if (!$formules instanceof Formules) { + $this->addFlash('error', 'Formule introuvable.'); + return $this->redirectToRoute('app_crm_formules'); + } + + // 2. Vérification du jeton CSRF (Sécurité contre les suppressions malveillantes) + // Note: Dans ton Twig, tu passes déjà le token en query string + if ($this->isCsrfTokenValid('delete' . $formules->getId(), $request->query->get('_token'))) { + $nomFormule = $formules->getName(); + + // 3. Suppression + foreach ($formules->getFormulesProductIncluses() as $formulesProductInclus) + $entityManager->remove($formulesProductInclus); + $entityManager->remove($formules); + $entityManager->flush(); + + // 4. Logging & Feedback + $appLogger->record('DELETE', 'Suppression définitive de la formule : ' . $nomFormule); + $this->addFlash('success', 'La formule "' . $nomFormule . '" a été supprimée.'); + } else { + $this->addFlash('error', 'Jeton de sécurité invalide.'); + } + + return $this->redirectToRoute('app_crm_formules'); + } + #[Route(path: '/crm/formules/add', name: 'app_crm_formules_add', methods: ['GET','POST'])] + public function formulesAdd(EntityManagerInterface $entityManager,PaginatorInterface $paginator,AppLogger $appLogger,Request $request,FormulesRepository $formulesRepository): Response { $appLogger->record('VIEW', 'Consultation page création formules'); $formules = new Formules(); + $formules->setIsPublish(false); $formules->setUpdatedAt(new \DateTimeImmutable()); $formules->setType($request->get('type',"pack")); // pack selected // free add listing allow product $form = $this->createForm(FormulesType::class,$formules); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - + $entityManager->persist($formules); + $entityManager->flush(); + $appLogger->record('CREATED', "Création de la formule : " . $formules->getName()); + $this->addFlash("success", "La formule a été créée avec succès."); + return $this->redirectToRoute('app_crm_formules_view',['id'=>$formules->getId()]); } return $this->render('dashboard/formules/add.twig', [ @@ -60,4 +98,41 @@ class FormulesController extends AbstractController ]); } + #[Route(path: '/crm/formules/{id}', name: 'app_crm_formules_view', methods: ['GET'])] + public function formulesView(?Formules $formules,Request $request,EntityManagerInterface $entityManager, AppLogger $appLogger): Response + { + if (!$formules instanceof Formules) { + $this->addFlash('error', 'Formule introuvable.'); + return $this->redirectToRoute('app_crm_formules'); + } + + $appLogger->record('VIEW', 'Consultation page formule ' . $formules->getName()); + + if ($request->get('act') === 'togglePublish') { + $status = $request->get('status') === 'true'; + $formules->setIsPublish($status); + $entityManager->flush(); + + $appLogger->record('UPDATE', ($status ? 'Publication' : 'Désactivation') . ' de la formule ' . $formules->getName()); + $this->addFlash('success', 'Statut mis à jour avec succès.'); + + return $this->redirectToRoute('app_crm_formules_view', ['id' => $formules->getId()]); + } + + $form = $this->createForm(FormulesType::class,$formules); + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $entityManager->persist($formules); + $entityManager->flush(); + $appLogger->record('CREATED', "Modification de la formule : " . $formules->getName()); + $this->addFlash("success", "La formule a été modifié avec succès."); + return $this->redirectToRoute('app_crm_formules_view',['id'=>$formules->getId()]); + } + return $this->render('dashboard/formules/view.twig', [ + 'formule' => $formules, + 'form' => $form->createView(), + 'type' => $formules->getType(), + ]); + } + } diff --git a/src/Entity/Formules.php b/src/Entity/Formules.php index 7801004..aa10289 100644 --- a/src/Entity/Formules.php +++ b/src/Entity/Formules.php @@ -5,6 +5,7 @@ namespace App\Entity; use App\Repository\FormulesRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\HttpFoundation\File\File; use Vich\UploaderBundle\Mapping\Attribute\Uploadable; @@ -43,6 +44,12 @@ class Formules #[ORM\OneToMany(targetEntity: FormulesProductInclus::class, mappedBy: 'formules')] private Collection $formulesProductIncluses; + #[ORM\Column(nullable: true)] + private ?bool $isPublish = null; + + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $description = null; + public function __construct() { $this->formulesProductIncluses = new ArrayCollection(); @@ -171,4 +178,28 @@ class Formules return $this; } + + public function isPublish(): ?bool + { + return $this->isPublish; + } + + public function setIsPublish(bool $isPublish): static + { + $this->isPublish = $isPublish; + + return $this; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDescription(?string $description): static + { + $this->description = $description; + + return $this; + } } diff --git a/src/Form/AccountType.php b/src/Form/AccountType.php index 0462156..837dabd 100644 --- a/src/Form/AccountType.php +++ b/src/Form/AccountType.php @@ -12,7 +12,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class AccountType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('username',TextType::class,[ @@ -33,7 +33,7 @@ class AccountType extends AbstractType ]); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefault('data_class',Account::class); } diff --git a/src/Form/CustomerAddAddressType.php b/src/Form/CustomerAddAddressType.php index 0ee5264..1275c3a 100644 --- a/src/Form/CustomerAddAddressType.php +++ b/src/Form/CustomerAddAddressType.php @@ -15,7 +15,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class CustomerAddAddressType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder @@ -50,7 +50,7 @@ class CustomerAddAddressType extends AbstractType ; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => CustomerAddress::class, diff --git a/src/Form/CustomerAddType.php b/src/Form/CustomerAddType.php index f7f2169..bf651c3 100644 --- a/src/Form/CustomerAddType.php +++ b/src/Form/CustomerAddType.php @@ -14,7 +14,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class CustomerAddType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('civ', ChoiceType::class, [ @@ -99,7 +99,7 @@ class CustomerAddType extends AbstractType ; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Customer::class, diff --git a/src/Form/CustomerType.php b/src/Form/CustomerType.php index fbf0f93..7a09b15 100644 --- a/src/Form/CustomerType.php +++ b/src/Form/CustomerType.php @@ -14,7 +14,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class CustomerType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('civ', ChoiceType::class, [ @@ -63,7 +63,7 @@ class CustomerType extends AbstractType ]); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Customer::class, diff --git a/src/Form/FormulesType.php b/src/Form/FormulesType.php index f14e40f..95fb8bc 100644 --- a/src/Form/FormulesType.php +++ b/src/Form/FormulesType.php @@ -5,18 +5,22 @@ namespace App\Form; use App\Entity\Formules; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\FileType; +use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class FormulesType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name',TextType::class,[ 'label' => 'Nom de la formule', ]) + ->add('description',TextareaType::class,[ + 'label' => 'Description de la formule', + ]) ->add('imageFile',FileType::class,[ 'label' => 'Image de la formule', 'required' => false, @@ -24,8 +28,8 @@ class FormulesType extends AbstractType ; } - public function configureOptions(OptionsResolver $resolver) - { + public function configureOptions(OptionsResolver $resolver): void + { $resolver->setDefault('data_class',Formules::class); } } diff --git a/src/Form/NewDevisType.php b/src/Form/NewDevisType.php index 320883e..8967f26 100644 --- a/src/Form/NewDevisType.php +++ b/src/Form/NewDevisType.php @@ -14,7 +14,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class NewDevisType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('num', TextType::class, [ diff --git a/src/Form/OptionsType.php b/src/Form/OptionsType.php index ea8794a..6ab359d 100644 --- a/src/Form/OptionsType.php +++ b/src/Form/OptionsType.php @@ -18,7 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class OptionsType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name',TextType::class,[ @@ -36,7 +36,7 @@ class OptionsType extends AbstractType ; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Options::class, diff --git a/src/Form/ProductDocType.php b/src/Form/ProductDocType.php index a9cf4ae..4d8c27b 100644 --- a/src/Form/ProductDocType.php +++ b/src/Form/ProductDocType.php @@ -18,7 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class ProductDocType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name', TextType::class, [ @@ -40,7 +40,7 @@ class ProductDocType extends AbstractType ; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => ProductDoc::class, diff --git a/src/Form/ProductType.php b/src/Form/ProductType.php index 54ed388..69ad92d 100644 --- a/src/Form/ProductType.php +++ b/src/Form/ProductType.php @@ -17,7 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class ProductType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name',TextType::class,[ @@ -81,7 +81,7 @@ class ProductType extends AbstractType ; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Product::class, diff --git a/templates/dashboard/formules.twig b/templates/dashboard/formules.twig index 1297984..27ca42c 100644 --- a/templates/dashboard/formules.twig +++ b/templates/dashboard/formules.twig @@ -1,15 +1,17 @@ {% extends 'dashboard/base.twig' %} {% block title %}Catalogue Formules{% endblock %} -{% block title_header %}Gestion du Formules{% endblock %} +{% block title_header %}Gestion des Formules{% endblock %} {% block actions %}
Aucune formules
+Aucune formule dans le catalogue
+