Files
ludikevent_crm/src/Controller/Dashboard/CustomerController.php
Serreau Jovann bd99d1af43 ```
 feat(Form/CustomerAddType): Ajoute formulaire pour créer un nouveau client.
 feat(Form/CustomerAddAddressType): Crée un formulaire pour gérer les adresses client.
 feat(template/customer): Affiche et permet l'édition des infos client et adresses.
♻️ refactor(Form/CustomerType): Simplifie le formulaire client.
🐛 fix(template/customer): Corrige l'affichage de la fiche client.
```
2026-01-16 14:52:30 +01:00

226 lines
8.8 KiB
PHP

<?php
namespace App\Controller\Dashboard;
use App\Entity\Customer;
use App\Entity\CustomerAddress;
use App\Form\CustomerAddAddressType;
use App\Form\CustomerAddType;
use App\Form\CustomerType;
use App\Logger\AppLogger;
use App\Repository\CustomerAddressRepository;
use App\Repository\CustomerRepository;
use App\Service\Search\Client;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class CustomerController extends AbstractController
{
public function __construct(
private readonly AppLogger $appLogger,
private readonly EntityManagerInterface $entityManager
) {}
#[Route(path: '/crm/customer', name: 'app_crm_customer', methods: ['GET'])]
public function index(
PaginatorInterface $paginator,
CustomerRepository $customerRepository,
Request $request
): Response {
$this->appLogger->record('VIEW', 'Consultation de la liste des clients');
// Utilisation d'un QueryBuilder (recommandé pour KNP) ou findAll
$query = $customerRepository->createQueryBuilder('c')
->orderBy('c.surname', 'ASC')
->getQuery();
$pagination = $paginator->paginate(
$query,
$request->query->getInt('page', 1),
20
);
return $this->render('dashboard/customer.twig', [
'customers' => $pagination,
]);
}
#[Route(path: '/crm/customer/add', name: 'app_crm_customer_add', methods: ['GET', 'POST'])]
public function add(Request $request, EntityManagerInterface $entityManager,\App\Service\Stripe\Client $client): Response
{
$this->appLogger->record('VIEW', 'Consultation de la page de création client');
$customer = new Customer();
$form = $this->createForm(CustomerAddType::class, $customer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data= $request->request->all()['customer_add'];
$userAddresse = new CustomerAddress();
$userAddresse->setCustomer($customer);
$userAddresse->setAddress($data['adresse']);
$userAddresse->setCity($data['city']);
$userAddresse->setZipcode($data['zipcode']);
$userAddresse->setCountry($data['country']);
$userAddresse->setAddress2($data['adresse2']);
$userAddresse->setAddress3($data['adresse3']);
$entityManager->persist($userAddresse);
// 1. Sauvegarde en base de données
$entityManager->persist($customer);
$entityManager->flush();
$client->createCustomer($customer);
// 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/edit/{id}', name: 'app_crm_customer_edit', methods: ['GET', 'POST'])]
public function edit(
int $id,
CustomerRepository $customerRepository,
CustomerAddressRepository $addressRepository, // Injecté pour charger l'adresse
Request $request,
EntityManagerInterface $entityManager,
\App\Service\Stripe\Client $stripeClient,
AppLogger $appLogger
): Response {
$customer = $customerRepository->find($id);
if (!$customer) {
throw $this->createNotFoundException('Client introuvable');
}
// --- LOGIQUE ADRESSE (ADD OU EDIT) ---
$idAddr = $request->query->get('idAddr');
if ($idAddr) {
// Mode ÉDITION d'adresse : on cherche l'adresse existante
$address = $addressRepository->findOneBy([
'id' => $idAddr,
'customer' => $customer // Sécurité : on vérifie que l'adresse appartient bien au client
]);
if (!$address) {
$this->addFlash('error', 'Adresse introuvable ou non associée à ce client.');
return $this->redirectToRoute('app_crm_customer_edit', ['id' => $customer->getId()]);
}
} else {
// Mode AJOUT : nouvelle instance
$address = new CustomerAddress();
$address->setCustomer($customer);
}
$formAddress = $this->createForm(CustomerAddAddressType::class, $address);
$formAddress->handleRequest($request);
if ($formAddress->isSubmitted() && $formAddress->isValid()) {
// Si c'est une nouvelle adresse, on doit faire persist
if (!$address->getId()) {
$entityManager->persist($address);
$logAction = 'Ajout';
} else {
$logAction = 'Modification';
}
$entityManager->flush();
$appLogger->record($idAddr ? 'EDIT' : 'CREATE', sprintf('%s adresse pour le client : %s', $logAction, $customer->getName()));
$this->addFlash('success', sprintf('L\'adresse a été %s avec succès.', $idAddr ? 'modifiée' : 'ajoutée'));
// On redirige vers la fiche sans le paramètre idAddr pour nettoyer l'URL
return $this->redirectToRoute('app_crm_customer_edit', ['id' => $customer->getId()]);
}
// --- LOGIQUE FORMULAIRE CLIENT (Reste identique) ---
$form = $this->createForm(CustomerType::class, $customer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($customer->getCustomerId()) {
try {
$stripeClient->updateCustomer($customer);
} catch (\Exception $e) {
$this->addFlash('warning', 'Erreur synchro Stripe : ' . $e->getMessage());
}
}
$entityManager->flush();
$appLogger->record('EDIT', sprintf('Modification du client : %s %s', $customer->getSurname(), $customer->getName()));
$this->addFlash('success', 'Les informations du client ont été mises à jour.');
return $this->redirectToRoute('app_crm_customer_edit', ['id' => $customer->getId()]);
}
if ($request->isMethod('GET')) {
$appLogger->record('VIEW', sprintf('Consultation de la fiche client : %s', $customer->getName()));
}
return $this->render('dashboard/customer/show.twig', [
'customer' => $customer,
'formAddress' => $formAddress->createView(),
'form' => $form->createView(),
'editingAddress' => (bool)$idAddr // Pour changer le texte du bouton dans le Twig
]);
}
#[Route(path: '/crm/customer/delete/{id}', name: 'app_crm_customer_delete', methods: ['GET', 'POST'])]
public function delete(
int $id,
CustomerRepository $customerRepository,
Request $request,
\App\Service\Stripe\Client $client,
AppLogger $appLogger,
EntityManagerInterface $entityManager
): Response {
$customer = $customerRepository->find($id);
if (!$customer) {
$this->addFlash('error', 'Le client demandé n\'existe pas.');
return $this->redirectToRoute('app_crm_customer');
}
// Récupération du token CSRF envoyé via data-turbo-method (dans l'URL)
$token = $request->query->get('_token');
if ($this->isCsrfTokenValid('delete' . $customer->getId(), $token)) {
// Log de l'action de suppression (avant suppression réelle)
$appLogger->record('DELETE', sprintf('Suppression définitive du client : %s %s', $customer->getSurname(), $customer->getName()));
// Suppression sur Stripe si l'ID existe
if ($customer->getCustomerId()) {
$client->deleteCustomer($customer->getCustomerId());
}
$entityManager->remove($customer);
$entityManager->flush();
$this->addFlash('success', sprintf('Le client %s %s a été supprimé définitivement.', $customer->getSurname(), $customer->getName()));
} else {
$this->addFlash('error', 'Jeton de sécurité invalide. La suppression a été annulée.');
}
return $this->redirectToRoute('app_crm_customer');
}
}