<?php
namespace App\Controller\Settings;
use App\Entity\CustomerCategory;
use App\Form\CustomerCategoryType;
use App\Repository\CustomerCategoryRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
/**
* @Route("/settings/customer-categories")
*/
class CustomerCategoryController extends AbstractController
{
private $entityManager;
private $customerCategoryRepository;
private $csrfTokenManager;
public function __construct(
EntityManagerInterface $entityManager,
CustomerCategoryRepository $customerCategoryRepository,
CsrfTokenManagerInterface $csrfTokenManager
) {
$this->entityManager = $entityManager;
$this->customerCategoryRepository = $customerCategoryRepository;
$this->csrfTokenManager = $csrfTokenManager;
}
/**
* @Route("", name="settings_customer_categories_index", methods={"GET"})
*/
public function index(): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$categories = $this->customerCategoryRepository->findAll();
// Calculer les statistiques
$totalClients = 0;
$mostUsedCategory = null;
$maxClients = 0;
foreach ($categories as $category) {
$clientCount = count($category->getCustomers());
$totalClients += $clientCount;
if ($clientCount > $maxClients) {
$maxClients = $clientCount;
$mostUsedCategory = $category;
}
}
return $this->render('settings/customer_categories/index.html.twig', [
'categories' => $categories,
'totalClients' => $totalClients,
'mostUsedCategory' => $mostUsedCategory,
]);
}
/**
* @Route("/form/new", name="settings_customer_categories_form_new", methods={"GET"})
*/
public function getNewForm(Request $request): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
if ($request->isXmlHttpRequest()) {
$category = new CustomerCategory();
$form = $this->createForm(CustomerCategoryType::class, $category, [
'action' => $this->generateUrl('settings_customer_categories_new'),
'method' => 'POST',
]);
return $this->render('settings/customer_categories/_form.html.twig', [
'form' => $form->createView(),
'category' => $category,
]);
}
return new JsonResponse(['error' => 'Invalid request'], 400);
}
/**
* @Route("/form/{id}/edit", name="settings_customer_categories_form_edit", methods={"GET"})
*/
public function getEditForm(Request $request, int $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$category = $this->customerCategoryRepository->find($id);
if (!$category) {
return new JsonResponse(['error' => 'Catégorie non trouvée'], 404);
}
if ($request->isXmlHttpRequest()) {
$form = $this->createForm(CustomerCategoryType::class, $category, [
'action' => $this->generateUrl('settings_customer_categories_edit', ['id' => $category->getId()]),
'method' => 'POST',
]);
return $this->render('settings/customer_categories/_form.html.twig', [
'form' => $form->createView(),
'category' => $category,
]);
}
return new JsonResponse(['error' => 'Invalid request'], 400);
}
/**
* @Route("/new", name="settings_customer_categories_new", methods={"POST"})
*/
public function new(Request $request): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
if ($request->isXmlHttpRequest()) {
try {
$data = $request->request->get('customer_category');
$token = $data['_token'] ?? null;
if (!$token || !$this->csrfTokenManager->isTokenValid(new CsrfToken('customer_category_type', $token))) {
return new JsonResponse([
'success' => false,
'message' => 'Token CSRF invalide',
'errors' => []
], 403);
}
$category = new CustomerCategory();
$category->setShortname($data['shortname']);
$category->setName($data['name']);
$this->entityManager->persist($category);
$this->entityManager->flush();
return new JsonResponse([
'success' => true,
'message' => 'Catégorie créée avec succès !',
'category' => [
'id' => $category->getId(),
'shortname' => $category->getShortname(),
'name' => $category->getName(),
'createdAt' => $category->getCreatedAt()->format('d/m/Y'),
]
]);
} catch (\Exception $e) {
return new JsonResponse([
'success' => false,
'message' => 'Erreur lors de la création : ' . $e->getMessage(),
'errors' => []
], 400);
}
} else {
return new JsonResponse([
'success' => false,
'message' => 'Requête invalide',
'errors' => []
], 400);
}
}
/**
* @Route("/{id}/edit", name="settings_customer_categories_edit", methods={"POST"})
*/
public function edit(Request $request, int $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$category = $this->customerCategoryRepository->find($id);
if (!$category) {
return new JsonResponse([
'success' => false,
'message' => 'Catégorie non trouvée',
'errors' => []
], 404);
}
if ($request->isXmlHttpRequest()) {
try {
$data = $request->request->get('customer_category');
$token = $data['_token'] ?? null;
if (!$token || !$this->csrfTokenManager->isTokenValid(new CsrfToken('customer_category_type', $token))) {
return new JsonResponse([
'success' => false,
'message' => 'Token CSRF invalide',
'errors' => []
], 403);
}
$category->setShortname($data['shortname']);
$category->setName($data['name']);
$this->entityManager->flush();
return new JsonResponse([
'success' => true,
'message' => 'Catégorie modifiée avec succès !',
'category' => [
'id' => $category->getId(),
'shortname' => $category->getShortname(),
'name' => $category->getName(),
'createdAt' => $category->getCreatedAt()->format('d/m/Y'),
'updatedAt' => $category->getUpdatedAt() ? $category->getUpdatedAt()->format('d/m/Y') : null,
]
]);
} catch (\Exception $e) {
return new JsonResponse([
'success' => false,
'message' => 'Erreur lors de la modification : ' . $e->getMessage(),
'errors' => []
], 400);
}
}
$form = $this->createForm(CustomerCategoryType::class, $category);
$form->handleRequest($request);
return $this->render('settings/customer_categories/index.html.twig', [
'categories' => $this->customerCategoryRepository->findAll(),
'form' => $form->createView(),
'category' => $category,
'errors' => $form->getErrors(true),
]);
}
/**
* @Route("/{id}/delete", name="settings_customer_categories_delete", methods={"POST"})
*/
public function delete(Request $request, int $id): Response
{
$this->denyAccessUnlessGranted('ROLE_SUPERADMIN');
$category = $this->customerCategoryRepository->find($id);
if (!$category) {
return new JsonResponse([
'success' => false,
'message' => 'Catégorie non trouvée',
'errors' => []
], 404);
}
if ($category->getCustomers()->count() > 0) {
return new JsonResponse([
'success' => false,
'message' => 'Impossible de supprimer cette catégorie car elle contient ' . $category->getCustomers()->count() . ' client(s).',
'errors' => ['Cette catégorie est liée à des clients. Veuillez d\'abord supprimer ou réaffecter les clients.']
], 400);
}
if ($request->isXmlHttpRequest()) {
try {
$this->entityManager->remove($category);
$this->entityManager->flush();
return new JsonResponse([
'success' => true,
'message' => 'Catégorie supprimée avec succès !',
'id' => $id
]);
} catch (\Exception $e) {
return new JsonResponse([
'success' => false,
'message' => 'Erreur lors de la suppression : ' . $e->getMessage()
], 500);
}
}
if ($this->isCsrfTokenValid('delete'.$category->getId(), $request->request->get('_token'))) {
$this->entityManager->remove($category);
$this->entityManager->flush();
$this->addFlash('success', 'Catégorie supprimée avec succès !');
}
return $this->redirectToRoute('settings_customer_categories_index');
}
/**
* @Route("/{id}/customers", name="settings_customer_categories_customers", methods={"GET"})
*/
public function customers(int $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$category = $this->customerCategoryRepository->find($id);
if (!$category) {
throw $this->createNotFoundException('Catégorie non trouvée');
}
return $this->render('settings/customer_categories/customers.html.twig', [
'category' => $category,
'customers' => $category->getCustomers(),
]);
}
/**
* @Route("/{id}/customers/export/excel", name="settings_customer_categories_customers_export_excel", methods={"GET"})
*/
public function exportCustomersExcel(int $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$category = $this->customerCategoryRepository->find($id);
if (!$category) {
throw $this->createNotFoundException('Catégorie non trouvée');
}
$customers = $category->getCustomers();
$exportService = new \App\Service\CustomerExportService();
$tempFile = $exportService->exportToExcel($customers->toArray());
$response = new Response(file_get_contents($tempFile));
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$response->headers->set('Content-Disposition', 'attachment; filename="clients_categorie_' . $category->getShortname() . '_' . date('Y-m-d_His') . '.xlsx"');
unlink($tempFile);
return $response;
}
/**
* @Route("/{id}/customers/export/pdf", name="settings_customer_categories_customers_export_pdf", methods={"GET"})
*/
public function exportCustomersPdf(int $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$category = $this->customerCategoryRepository->find($id);
if (!$category) {
throw $this->createNotFoundException('Catégorie non trouvée');
}
$customers = $category->getCustomers();
$exportService = new \App\Service\CustomerExportService();
// Chemin vers le logo (à adapter selon votre structure)
$logoPath = $this->getParameter('kernel.project_dir') . '/public/images/logo.png';
if (!file_exists($logoPath)) {
$logoPath = null;
}
$tempFile = $exportService->exportToPdf($customers->toArray(), $logoPath);
$response = new Response(file_get_contents($tempFile));
$response->headers->set('Content-Type', 'application/pdf');
$response->headers->set('Content-Disposition', 'attachment; filename="clients_categorie_' . $category->getShortname() . '_' . date('Y-m-d_His') . '.pdf"');
unlink($tempFile);
return $response;
}
}