diff --git a/src/Command/SearchCommand.php b/src/Command/SearchCommand.php index 8071cd1..65accb9 100644 --- a/src/Command/SearchCommand.php +++ b/src/Command/SearchCommand.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Command; use App\Entity\Account; +use App\Entity\Customer; use App\Service\Search\Client; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Console\Attribute\AsCommand; @@ -42,6 +43,23 @@ class SearchCommand extends Command $this->client->indexDocuments($datas, 'admin'); } + $customers = $this->entityManager->getRepository(Customer::class)->findAll(); + + foreach ($customers as $customer) { + + $datas = [ + 'id' => $customer->getId(), + 'name' => $customer->getName(), + 'surname' => $customer->getSurname(), + 'siret' => $customer->getSiret(), + 'civ' => $customer->getCiv(), + 'type' => $customer->getType(), + 'phone' => $customer->getPhone(), + 'email' => $customer->getEmail(), + ]; + + $this->client->indexDocuments($datas, 'customer'); + } $output->writeln('Indexation terminée (hors ROOT).'); return Command::SUCCESS; diff --git a/src/Controller/Dashboard/CustomerController.php b/src/Controller/Dashboard/CustomerController.php index 3728b85..d9c0e7f 100644 --- a/src/Controller/Dashboard/CustomerController.php +++ b/src/Controller/Dashboard/CustomerController.php @@ -3,6 +3,7 @@ namespace App\Controller\Dashboard; use App\Entity\Customer; +use App\Form\CustomerType; use App\Logger\AppLogger; use App\Repository\CustomerRepository; use Doctrine\ORM\EntityManagerInterface; @@ -42,17 +43,39 @@ class CustomerController extends AbstractController 'customers' => $pagination, ]); } - #[Route(path: '/crm/customer/add', name: 'app_crm_customer_add', methods: ['GET', 'POST'])] - public function add(Request $request): Response + public function add(Request $request, EntityManagerInterface $entityManager): Response { $this->appLogger->record('VIEW', 'Consultation de la page de création client'); - $c = new Customer(); - //$form = $this->createForm(,$c); - // Ici, tu pourras ajouter ta logique de formulaire (CustomerType) + $customer = new Customer(); + $form = $this->createForm(CustomerType::class, $customer); - return $this->render('dashboard/customer/add.twig'); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + // 1. Sauvegarde en base de données + $entityManager->persist($customer); + $entityManager->flush(); + + // 2. Log de l'action de création + $this->appLogger->record('CREATE', sprintf( + 'Nouveau client créé : %s %s (Type: %s)', + $customer->getSurname(), + $customer->getName(), + $customer->getType() + )); + + // 3. Notification flash pour l'utilisateur + $this->addFlash('success', 'Le client a été enregistré avec succès.'); + + // 4. Redirection vers la liste + return $this->redirectToRoute('app_crm_customer'); + } + + return $this->render('dashboard/customer/add.twig', [ + 'form' => $form->createView(), + ]); } #[Route(path: '/crm/customer/show/{id}', name: 'app_crm_customer_show', methods: ['GET'])] diff --git a/src/Controller/Dashboard/SearchController.php b/src/Controller/Dashboard/SearchController.php index 549223d..dee5b5d 100644 --- a/src/Controller/Dashboard/SearchController.php +++ b/src/Controller/Dashboard/SearchController.php @@ -8,6 +8,7 @@ use App\Entity\AccountResetPasswordRequest; use App\Form\RequestPasswordConfirmType; use App\Form\RequestPasswordRequestType; use App\Repository\AccountRepository; +use App\Repository\CustomerRepository; use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent; use App\Service\ResetPassword\Event\ResetPasswordEvent; use App\Service\Search\Client; @@ -27,6 +28,7 @@ class SearchController extends AbstractController #[Route(path: '/crm/recherche', name: 'app_crm_search', options: ['sitemap' => false], methods: ['GET'])] public function crmSearch( AccountRepository $accountRepository, + CustomerRepository $customerRepository, Client $client, Request $request ): Response { @@ -37,6 +39,22 @@ class SearchController extends AbstractController $response = $client->searchGlobal($query, 20); foreach ($response['results'] as $resultGroup) { + if (str_contains($resultGroup['indexUid'], 'intranet_ludikevent_customer')) { + // Extraction des IDs pour éviter les requêtes en boucle + $ids = array_map(fn($h) => $h['id'], $resultGroup['hits']); + $accounts = $customerRepository->findBy(['id' => $ids]); + + foreach ($accounts as $account) { + $unifiedResults[] = [ + 'title' => $account->getName() . " " . $account->getSurname(), + 'subtitle' => $account->getEmail(), + 'link' => $this->generateUrl('app_crm_customer_show', ['id' => $account->getId()]), + 'type' => 'Client', + 'id' => $account->getId(), + 'initials' => strtoupper(substr($account->getName(), 0, 1) . substr($account->getSurname(), 0, 1)) + ]; + } + } // On vérifie si l'index correspond aux administrateurs if (str_contains($resultGroup['indexUid'], 'intranet_ludikevent_admin')) { diff --git a/src/Form/CustomerType.php b/src/Form/CustomerType.php new file mode 100644 index 0000000..c23d2f2 --- /dev/null +++ b/src/Form/CustomerType.php @@ -0,0 +1,71 @@ +add('civ', ChoiceType::class, [ + 'label' => 'Civilité', + 'choices' => [ + 'Monsieur' => 'M.', + 'Madame' => 'Mme', + ], + 'expanded' => false, + 'multiple' => false, + ]) + ->add('surname', TextType::class, [ + 'label' => 'Prénom', + 'attr' => ['placeholder' => 'ex: Jean'], + 'required' => true, + ]) + ->add('name', TextType::class, [ + 'label' => 'Nom', + 'attr' => ['placeholder' => 'ex: DUPONT'], + 'required' => true, + ]) + ->add('type', ChoiceType::class, [ + 'label' => 'Type de client', + 'choices' => [ + 'Particulier' => 'personal', + 'Entreprise' => 'company', + 'Association' => 'association', + 'Mairie / Collectivité' => 'mairie', + ], + ]) + ->add('email', EmailType::class, [ + 'label' => 'Adresse Email', + 'attr' => ['placeholder' => 'contact@exemple.fr'], + 'required' => true, + ]) + ->add('phone', TelType::class, [ // TelType est plus adapté pour mobile + 'label' => 'Téléphone', + 'attr' => ['placeholder' => '06 .. .. .. ..'], + 'required' => true, + ]) + ->add('siret', TextType::class, [ + 'label' => 'Numéro SIRET', + 'required' => false, + 'attr' => ['placeholder' => '14 chiffres'], + 'help' => 'Obligatoire pour les entreprises et mairies', + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => Customer::class, + ]); + } +} diff --git a/src/Service/Search/Client.php b/src/Service/Search/Client.php index 66a735f..f2f26fd 100644 --- a/src/Service/Search/Client.php +++ b/src/Service/Search/Client.php @@ -29,6 +29,7 @@ class Client { return [ "intranet_ludikevent_admin" => [], + "intranet_ludikevent_customer" => [], ]; } diff --git a/templates/dashboard/customer.twig b/templates/dashboard/customer.twig index a1486aa..e55bee3 100644 --- a/templates/dashboard/customer.twig +++ b/templates/dashboard/customer.twig @@ -54,7 +54,7 @@ {{ customer.civ }} {{ customer.surname|upper }} {{ customer.name }} -
Client ID: #{{ loop.index + 100 }}
+
Client ID: #{{ customer.id }}
diff --git a/templates/dashboard/customer/add.twig b/templates/dashboard/customer/add.twig new file mode 100644 index 0000000..158ab06 --- /dev/null +++ b/templates/dashboard/customer/add.twig @@ -0,0 +1,119 @@ +{% extends 'dashboard/base.twig' %} + +{% block title %}Nouveau Client{% endblock %} +{% block title_header %}Ajouter un Client{% endblock %} + +{% block body %} +
+ + {# Navigation haute #} +
+ + + + + Annuaire Clients + +
+ + {# Carte Full Width #} +
+ +
+
+

Fiche d'identification

+

Saisie des informations de compte

+
+
+ +
+ {{ form_start(form, {'attr': {'class': 'space-y-12'}}) }} + + {# SECTION 1 : IDENTITÉ & TYPE (Pleine largeur) #} +
+
+ + Identité & Type +
+ +
+
+ {{ form_label(form.civ) }} + {{ form_widget(form.civ) }} +
+
+ {{ form_label(form.surname) }} + {{ form_widget(form.surname) }} +
+
+ {{ form_label(form.name) }} + {{ form_widget(form.name) }} +
+
+ +
+
+ {{ form_label(form.type) }} + {{ form_widget(form.type) }} +
+
+ {{ form_label(form.siret) }} + {{ form_widget(form.siret) }} +
+
+
+ + {# SECTION 2 : CONTACT (Ratio 50/50 exact) #} +
+
+ + Contact +
+ +
+
+ {{ form_label(form.email) }} + {{ form_widget(form.email) }} +
+
+ {{ form_label(form.phone) }} + {{ form_widget(form.phone) }} +
+
+
+ + {# ACTIONS : Boutons espacés #} +
+
{# Espace large entre les deux boutons #} + + Annuler l'opération + + +
+
+ + {{ form_end(form) }} +
+
+
+ + +{% endblock %}