✨ 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. ```
226 lines
8.8 KiB
PHP
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');
|
|
}
|
|
}
|