src/Controller/NetworkController.php line 288

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use App\Entity\Commission;
  5. use App\Entity\Customer;
  6. use App\Entity\Device;
  7. use App\Entity\Motif;
  8. use App\Entity\NanoEntrepreneur;
  9. use App\Entity\Network;
  10. use App\Entity\NetworkComment;
  11. use App\Entity\NetworkDevice;
  12. use App\Entity\NetworkHistoric;
  13. use App\Entity\ReadOnly;
  14. use App\Entity\Task;
  15. use App\Entity\Users;
  16. use App\Form\Type\CommissionFormType;
  17. use App\Form\Type\CommissionNanoEntrepreneurFormType;
  18. use App\Form\Type\NetworkFormType;
  19. use App\Manager\NetworkManager;
  20. use App\Manager\RequestParamsManager;
  21. use App\Manager\RoleManager;
  22. use App\Manager\SynchroOdooManager;
  23. use App\Manager\ZoneManager;
  24. use Doctrine\ORM\EntityManagerInterface;
  25. use Knp\Component\Pager\Paginator;
  26. use App\Processor\ProjectWorkflowProcessor;
  27. use Doctrine\ORM\EntityManager;
  28. use PHPExcel_Shared_Date;
  29. use Psr\Log\LoggerInterface;
  30. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  31. use Symfony\Component\HttpFoundation\JsonResponse;
  32. use Symfony\Component\HttpFoundation\RedirectResponse;
  33. use Symfony\Component\HttpFoundation\Request;
  34. use Symfony\Component\HttpFoundation\Response;
  35. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  36. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  37. use Symfony\Component\HttpFoundation\StreamedResponse;
  38. use App\Annotation\IgnoreSoftDelete;
  39. use Knp\Component\Pager\PaginatorInterface;
  40. use App\Entity\Zone;
  41. use Doctrine\ORM\QueryBuilder;
  42. use Doctrine\ORM\Tools\Pagination\Paginator as PaginationPaginator;
  43. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  44. use Symfony\Contracts\Translation\TranslatorInterface;
  45. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  46. use Knp\Snappy\Pdf;
  47. use Symfony\Component\DependencyInjection\ContainerInterface;
  48. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  49. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  50. class NetworkController extends AbstractController
  51. {
  52.     private $oNetworkManager;
  53.     private $zoneManager;
  54.     private $entityManager;
  55.     private $requestParamsManager;
  56.     private $paginator;
  57.     private $_em;
  58.     private $oSynchroOdoo;
  59.     private $translatorInterface;
  60.     private $networkManager;
  61.     /**
  62.      * @var ContainerInterface
  63.      */
  64.     protected $container;
  65.     public function __construct(
  66.         NetworkManager $oNetworkManager,
  67.         ZoneManager $zoneManager,
  68.         RequestParamsManager $requestParamsManager,
  69.         EntityManagerInterface $em,
  70.         SynchroOdooManager $oSynchroOdoo,
  71.         ContainerInterface $container,
  72.         AuthorizationCheckerInterface $authorizationChecker,
  73.         TranslatorInterface $translatorInterface,
  74.         EntityManagerInterface $entityManager,
  75.         $networkManager null
  76.     ) {
  77.         $this->oSynchroOdoo $oSynchroOdoo;
  78.         $this->oNetworkManager $oNetworkManager;
  79.         $this->zoneManager $zoneManager;
  80.         $this->requestParamsManager $requestParamsManager;
  81.         $this->_em $em;
  82.         $this->container $container;
  83.         $this->authorizationChecker $authorizationChecker;
  84.         $this->translatorInterface $translatorInterface;
  85.         $this->entityManager $entityManager;
  86.         $this->networkManager $networkManager;
  87.     }
  88.     private function setAccessZoneParams(&$queryParams = [])
  89.     {
  90.         if (!$this->authorizationChecker->isGranted('ROLE_SUPER_ADMIN')) {
  91.             $currentUser $this->container->get('security.token_storage')->getToken()->getUser();
  92.             $queryParams['filtered_by_user_zone'] = true;
  93.             $queryParams['user_id'] = $currentUser->getId();
  94.             $queryParams['zones'] = [];
  95.             foreach ($currentUser->getZone() as $zone) {
  96.                 array_push($queryParams['zones'], $zone->getId());
  97.             }
  98.             if (
  99.                 $this->authorizationChecker->isGranted('ROLE_EQUIPE') ||
  100.                 $this->authorizationChecker->isGranted('ROLE_ADMIN')
  101.             ) {
  102.                 $queryParams['access_child_zone'] = true;
  103.             }
  104.         }
  105.     }
  106.     /**
  107.      * @param EntityManager $em
  108.      * @return Response
  109.      */
  110.     public function listAction(EntityManager $emRequest $requestTranslatorInterface $translatorInterfacePaginatorInterface $paginatorInterface)
  111.     {
  112.         $this->denyAccessUnlessGranted(RoleManager::ROLE_ENTREPRENEUR$this->getUser());
  113.         $queryParams['status'] = Network::STATUS_NETWORK;
  114.         if (!$this->isGranted(RoleManager::ROLE_EQUIPE$this->getUser())) {
  115.             $queryParams['owner'] = $this->getUser();
  116.         }
  117.         if ($request->isXmlHttpRequest()) {
  118.             $queryParams array_merge($queryParams$this->requestParamsManager->initQueryParams($request));
  119.             $this->setAccessZoneParams($queryParams);
  120.             $networks $em->getRepository('App\Entity\Network')->searchQuery($queryParams);
  121.             $this->paginator $paginatorInterface;
  122.             $networks $this->paginator->paginate(
  123.                 $networks/* query NOT result */
  124.                 $request->query->getInt('page'1)/*page number*/,
  125.                 $request->query->getInt('limit'25)/*limit per page*/,
  126.                 array('wrap-queries' => true)
  127.             );
  128.             // foreach ($networks as $net) {
  129.             //     return print_r($net);
  130.             //     break;
  131.             // }
  132.             $table $this->renderView(
  133.                 "@App/Network/table.html.twig",
  134.                 array(
  135.                     'networks' => $networks
  136.                 )
  137.             );
  138.             $response = new Response(json_encode([
  139.                 'table' => $table,
  140.             ]));
  141.             $response->headers->set('Content-Type''application/json');
  142.             return $response;
  143.         }
  144.         $zonesTypes['zones'] = $this->zoneManager->getAllZoneType();
  145.         $zonesTypes['types'] = ['TYPE_ZONE'];
  146.         $allDistrict $this->zoneManager->getAllDistrict();
  147.         $district $request->query->get('district_id');
  148.         $nanoEntrepneneur $request->query->get('ne_id');
  149.         $limits = [102550100];
  150.         return $this->render('@App/Network/list.html.twig', [
  151.             'isXmlHttpRequest' => false,
  152.             'pageTitle' => $translatorInterface->trans('Nano-Grids'),
  153.             'types' => $zonesTypes['types'],
  154.             'zones' => $zonesTypes['zones'],
  155.             'limits' => $limits,
  156.             'district_id' => $district $district false,
  157.             'ne_id' => $nanoEntrepneneur $nanoEntrepneneur false,
  158.             'districts' => $allDistrict
  159.         ]);
  160.     }
  161.     public function mapAction()
  162.     {
  163.         if (!$this->isGranted(RoleManager::ROLE_ENTREPRENEUR$this->getUser())) {
  164.             $this->addFlash('error''You are not authorized to access this section');
  165.             return $this->redirectToRoute('app.client.list');
  166.         }
  167.         $queryParams = [];
  168.         $em $this->container->get('doctrine')->getManager();
  169.         if (!$this->isGranted(RoleManager::ROLE_EQUIPE$this->getUser())) {
  170.             $queryParams = ['owner' => $this->getUser(), 'status' => 'network'];
  171.         } else {
  172.             $queryParams = ['status' => 'network'];
  173.         }
  174.         $networks $em->getRepository('App\Entity\Network')->findBy($queryParams);
  175.         $validCustomer = [];
  176.         //Customers with coordinates are considered valid
  177.         foreach ($networks as $network) {
  178.             $customers $network->getCustomers();
  179.             foreach ($customers as $customer) {
  180.                 if ($customer->getPicturePath()) {
  181.                     $img $this->getParameter('customer_picture_dir') . $customer->getId()
  182.                         . DIRECTORY_SEPARATOR $customer->getPicturePath();
  183.                 } elseif ($customer->getBuilding()->getPicturePath()) {
  184.                     $img $this->getParameter('building_picture_dir') . $customer->getBuilding()->getId()
  185.                         . DIRECTORY_SEPARATOR $customer->getBuilding()->getPicturePath();
  186.                 } else {
  187.                     $img null;
  188.                 }
  189.                 if ($customer->getLocalizationLat() && $customer->getLocalizationLong()) {
  190.                     $validCustomer[] = [
  191.                         'status' => $customer->getWorkflowState() === 'validated' 'Client' 'Prospect',
  192.                         'id' => $customer->getId(),
  193.                         'lat' => $customer->getLocalizationLat(),
  194.                         'lng' => $customer->getLocalizationLong(),
  195.                         'name' => $customer->getFullName(),
  196.                         'prospectNumber' => $customer->isClient() ? $customer->getCustomNumber() : $customer->getProspectNumber(),
  197.                         'totalEstimation' => $customer->getTotalPriceEstimation(),
  198.                         'offer' => $customer->getOffer() ? $customer->getOffer()->getTitle() : null,
  199.                         'paidFees' => $customer->hasPaidInstallationFees(),
  200.                         'wall' => $customer->getBuilding()->getWallType() ?: 'N/A',
  201.                         'roof' => $customer->getBuilding()->getRoofType() ?: 'N/A',
  202.                         'usage' => $customer->getBuilding()->getUsage() ?: 'N/A',
  203.                         'img' => $img,
  204.                         'numClient' => $customer->getCustomNumber(),
  205.                         'numProspect' => $customer->getProspectNumber()
  206.                     ];
  207.                 }
  208.             }
  209.         }
  210.         return $this->render('Network/map.html.twig', [
  211.             'pageTitle' => 'Nano-' $translatorInterface->trans('Grid'),
  212.             'customers' => $validCustomer,
  213.             'networks' => [],
  214.         ]);
  215.     }
  216.     /**
  217.      * @param Network $network
  218.      * @param EntityManager $em
  219.      * @return JsonResponse
  220.      * @throws \Doctrine\ORM\ORMException
  221.      */
  222.     public function getDevicesAction(Network $networkEntityManager $em)
  223.     {
  224.         $networkDevices $em->getRepository(Device::class)->getByNetwork($network);
  225.         $devices = [];
  226.         /** @var Device $networkDevice */
  227.         foreach ($networkDevices as $networkDevice) {
  228.             $devices[] = [
  229.                 'id' => $networkDevice->getId(),
  230.                 'name' => $networkDevice->getName(),
  231.             ];
  232.         }
  233.         return new JsonResponse($devices);
  234.     }
  235.     /**
  236.      * @param Network $network
  237.      * @param EntityManager $em
  238.      * @param Request $request
  239.      * @return Response
  240.      * @throws \Doctrine\ORM\ORMException
  241.      * @throws \Doctrine\ORM\OptimisticLockException
  242.      */
  243.     public function editAction(Network $networkEntityManager $emRequest $requestLoggerInterface $loggerProjectWorkflowProcessor $processorTranslatorInterface $translatorInterface)
  244.     {
  245.         $this->denyAccessUnlessGranted(RoleManager::ROLE_ENTREPRENEUR$this->getUser());
  246.         $form $this->createForm(NetworkFormType::class, $network, array("user" => $this->getUser(), "removed" => $network->getDeviceDeleted(), "numberNetwork" => $network->getNetworkNumber()));
  247.         $form->handleRequest($request);
  248.         $zone $network->getZone();
  249.         $user $this->getUser();
  250.         $oReadOnly $em->getRepository('App\Entity\ReadOnly')->findBy(
  251.             array(
  252.                 'zone' => $zone,
  253.                 'user' => $user,
  254.             )
  255.         );
  256.         if (!empty($oReadOnly) && is_array($oReadOnly) && !$this->isGranted(RoleManager::ROLE_ADMIN)) {
  257.             $this->addFlash('error'$translatorInterface->trans('You cannot edit this nano-grid'));
  258.             return $this->redirectToRoute('app.network.list');
  259.         }
  260.         if ($form->isSubmitted() && $form->isValid()) {
  261.             $session $request->getSession();
  262.             if ($session->get('added_customer')) {
  263.                 $session->remove('added_customer');
  264.             }
  265.             try {
  266.                 /*$em->persist($network);
  267.                  */
  268.                 $this->oNetworkManager->updateCustomerZone($network);
  269.                 $em->flush();
  270.                 $this->addFlash('success'$translatorInterface->trans('The nano-grid was successfully modified'));
  271.                 return $this->redirectToRoute('app.network.list');
  272.             } catch (\Exception $e) {
  273.                 $this->addFlash('error'$translatorInterface->trans('An error occurred, please try again'));
  274.                 $logger->error($e->getMessage(), [__CLASS__ => __FUNCTION__]);
  275.             }
  276.         }
  277.         $transition Network::TRANSITION_VALIDATE_FINAL_DECISION;
  278.         $networkHistoricRepo $em->getRepository("App\Entity\NetworkHistoric");
  279.         $aoNetworkHistoric $networkHistoricRepo->findBy(array("statut" => $transition"network" => $network));
  280.         $aCustomers $this->getListCustomer($network$translatorInterface);
  281.         $returnData = [];
  282.         $networkId $network->getId();
  283.         $commentData $em->getRepository("App\Entity\NetworkComment")
  284.             ->findBy(['owner' => $networkId], ['id' => 'DESC']);
  285.         foreach ($commentData as $comment) {
  286.             $returnData[] = [
  287.                 'owner' => $comment->getOwner()->getId(),
  288.                 'writer' => [
  289.                     'id' => $comment->getWriter()->getId(),
  290.                     'name' => $comment->getWriter()->getFirstname() . ' ' $comment->getWriter()->getLastname()
  291.                 ],
  292.                 'content' => $comment->getContent(),
  293.                 'dateCreation' => $comment->getDateCreation()->format('c'),
  294.             ];
  295.         }
  296.         return $this->render('@App/Network/form.html.twig', [
  297.             'pageTitle' => $translatorInterface->trans('Editing a Nano-grid'),
  298.             'network' => $network,
  299.             'form' => $form->createView(),
  300.             'networkHistorics' => $aoNetworkHistoric,
  301.             'customers' => $aCustomers,
  302.             'networkComments' => $returnData,
  303.             'history' => $network->getDeviceDeleted()
  304.         ]);
  305.     }
  306.     private function getListCustomer($networksTranslatorInterface $translatorInterface)
  307.     {
  308.         $this->addFlash('error'$translatorInterface->trans('You are not authorized to access this section'));
  309.         if (!$this->isGranted(RoleManager::ROLE_ENTREPRENEUR$this->getUser())) {
  310.             $this->addFlash('error'$translatorInterface->trans('You are not authorized to access this section'));
  311.             return $this->redirectToRoute('app.client.list');
  312.         }
  313.         $validCustomers = [];
  314.         //Customers with coordinates are considered valid
  315.         $customers $networks->getCustomers();
  316.         foreach ($customers as $customer) {
  317.             if ($customer->getPicturePath()) {
  318.                 $img $this->getParameter('customer_picture_dir') . $customer->getId()
  319.                     . DIRECTORY_SEPARATOR $customer->getPicturePath();
  320.             } elseif ($customer->getBuilding()->getPicturePath()) {
  321.                 $img $this->getParameter('building_picture_dir') . $customer->getBuilding()->getId()
  322.                     . DIRECTORY_SEPARATOR $customer->getBuilding()->getPicturePath();
  323.             } else {
  324.                 $img null;
  325.             }
  326.             if ($customer->getLocalizationLat() && $customer->getLocalizationLong()) {
  327.                 $validCustomers[] = [
  328.                     'status' => $customer->getWorkflowState() === 'validated' 'Client' 'Prospect',
  329.                     'id' => $customer->getId(),
  330.                     'lat' => $customer->getLocalizationLat(),
  331.                     'lng' => $customer->getLocalizationLong(),
  332.                     'name' => $customer->getFullName(),
  333.                     'prospectNumber' => $customer->isClient() ? $customer->getCustomNumber() : $customer->getProspectNumber(),
  334.                     'totalEstimation' => $customer->getTotalPriceEstimation(),
  335.                     'offer' => $customer->getOffer() ? $customer->getOffer()->getTitle() : null,
  336.                     'paidFees' => $customer->hasPaidInstallationFees(),
  337.                     'wall' => $customer->getBuilding()->getWallType() ?: 'N/A',
  338.                     'roof' => $customer->getBuilding()->getRoofType() ?: 'N/A',
  339.                     'usage' => $customer->getBuilding()->getUsage() ?: 'N/A',
  340.                     'img' => $img,
  341.                 ];
  342.             }
  343.         }
  344.         return $validCustomers;
  345.     }
  346.     /**
  347.      * @param Network $network
  348.      * @return Response
  349.      */
  350.     public function showAction(Network $network)
  351.     {
  352.         return $this->render('@App/Network/_show_modal.html.twig', [
  353.             'network' => $network,
  354.         ]);
  355.     }
  356.     /**
  357.      * @param EntityManager $em
  358.      * @param Network $network
  359.      * @return JsonResponse
  360.      */
  361.     public function updateNetworkLocationAction(NetworkManager $managerRequest $requestNetwork $networkTranslatorInterface $translatorInterface)
  362.     {
  363.         // TODO gestion des roles
  364.         $user $this->getUser();
  365.         $canMove $this->isGranted(RoleManager::ROLE_EQUIPE$user);
  366.         if (!$this->isGranted(RoleManager::ROLE_ENTREPRENEUR$user)) {
  367.             return new JsonResponse([], Response::HTTP_FORBIDDEN);
  368.         }
  369.         $status Response::HTTP_OK;
  370.         $msg "%s a été mise à jour";
  371.         $statusText 'ok';
  372.         $data $request->request->all();
  373.         if ($canMove) {
  374.             try {
  375.                 $ret $manager->updateLocation($data$network);
  376.                 if (!$ret && $canMove) {
  377.                     $msg "%s 'a pas été mise à jour";
  378.                     $status Response::HTTP_BAD_REQUEST;
  379.                 }
  380.             } catch (\Exception $e) {
  381.                 $status Response::HTTP_BAD_REQUEST;
  382.                 $statusText 'ko';
  383.                 $message $translatorInterface->trans('An error occurred, please try again');
  384.             }
  385.         } else {
  386.             $msg $translatorInterface->trans('The request to move') . " %s " $translatorInterface->trans('has been sent');
  387.             $manager->addMoveRequest($network$user$data);
  388.         }
  389.         $message sprintf($msg$network->getName());
  390.         $toReturn = [
  391.             'status' => $statusText,
  392.             'message' => $message,
  393.             'canMove' => $canMove,
  394.         ];
  395.         return new JsonResponse($toReturn$status);
  396.     }
  397.     /**
  398.      * @param EntityManager $em
  399.      * @return Response
  400.      */
  401.     public function commissionListAction(EntityManagerInterface $emTranslatorInterface $translatorRequest $request)
  402.     {
  403.         $this->denyAccessUnlessGranted(RoleManager::ROLE_ENTREPRENEUR$this->getUser());
  404.         $em->getFilters()->disable('softdeleteable');
  405.         // 🔹 Récupération des paramètres GET
  406.         $page max(1, (int) $request->query->get('page'1));
  407.         $limit = (int) $request->query->get('limit'25);
  408.         $offset = ($page 1) * $limit;
  409.         $nanoReseau trim($request->query->get('nanoReseau'''));
  410.         $nanoEntrepreneur trim($request->query->get('nanoEntrepreneur'''));
  411.         $district trim($request->query->get('district'''));
  412.         $dateFrom $request->query->get('d1');
  413.         $dateTo $request->query->get('d2');
  414.         // 🔹 Requête principale
  415.         $qb $em->getRepository(Network::class)->createQueryBuilder('n')
  416.             ->leftJoin('n.owner''o')
  417.             ->leftJoin('n.zone''z')
  418.             ->where('n.status = :status')
  419.             ->setParameter('status'Network::STATUS_NETWORK)
  420.             ->orderBy('n.id''ASC');
  421.         // 🔹 Requête COUNT séparée
  422.         $countQb $em->getRepository(Network::class)->createQueryBuilder('n')
  423.             ->select('COUNT(n.id)')
  424.             ->leftJoin('n.owner''o')
  425.             ->leftJoin('n.zone''z')
  426.             ->where('n.status = :status')
  427.             ->setParameter('status'Network::STATUS_NETWORK);
  428.         // 🔸 Appliquer les filtres aux deux requêtes
  429.         $this->applyFilters($qb$nanoReseau$nanoEntrepreneur$district$dateFrom$dateTo);
  430.         $this->applyFilters($countQb$nanoReseau$nanoEntrepreneur$district$dateFrom$dateTo);
  431.         // 🔹 Comptage total
  432.         $totalItems = (int) $countQb->getQuery()->getSingleScalarResult();
  433.         $totalPages ceil($totalItems $limit);
  434.         // 🔹 Application de la pagination à la requête principale
  435.         $qb->setFirstResult($offset)->setMaxResults($limit);
  436.         $results $qb->getQuery()->getResult();
  437.         // 🔹 Formatage des données
  438.         $aNetworks = [];
  439.         foreach ($results as $network) {
  440.             $aCommissionEntrepreneurs $network->getCommissionEntrepreneurs();
  441.             $aNanoEntrepreneurs $network->getNanoEntrepreneurs();
  442.             if (!empty($aNanoEntrepreneurs)) {
  443.                 $aNetworks array_merge(
  444.                     $aNetworks,
  445.                     $this->oNetworkManager->getCommissionForEntrepreneurs($aNanoEntrepreneurs$network)
  446.                 );
  447.             }
  448.             if (empty($aNanoEntrepreneurs) && empty($aCommissionEntrepreneurs)) {
  449.                 $aNetworks[] = [
  450.                     'networkId' => $network->getId(),
  451.                     'networkNumber' => $network->getNetworkNumber(),
  452.                     'owner' => $network->getOwner()->getFirstname() . ' ' $network->getOwner()->getLastname(),
  453.                     'entrepreneurStartDate' => $network->getDateStartService(),
  454.                     'entrepreneurEndDate' => 'actif',
  455.                     'commissionStartDate' => $network->getDateStartService(),
  456.                     'commissionEndDate' => 'actif',
  457.                     'commission' => $network->getCommissionPercentage(),
  458.                     'zone' => $network->getZone(),
  459.                     'network' => $network
  460.                 ];
  461.             }
  462.         }
  463.         $districts $em->getRepository(Zone::class)->getDistrict();
  464.         return $this->render('@App/Network/commissionList.html.twig', [
  465.             'networks' => $aNetworks,
  466.             'pageTitle' => 'Nano-' $translator->trans('Grid'),
  467.             'districts' => $districts,
  468.             'currentPage' => $page,
  469.             'totalPages' => $totalPages,
  470.             'limit' => $limit,
  471.             'totalItems' => $totalItems,
  472.             'filters' => [
  473.                 'nanoReseau' => $nanoReseau,
  474.                 'nanoEntrepreneur' => $nanoEntrepreneur,
  475.                 'district' => $district,
  476.                 'd1' => $dateFrom,
  477.                 'd2' => $dateTo,
  478.             ],
  479.         ]);
  480.     }
  481.     /**
  482.      * 🔸 Applique les filtres aux QueryBuilder
  483.      */
  484.     private function applyFilters(QueryBuilder $qbstring $nanoReseaustring $nanoEntrepreneurstring $district, ?string $dateFrom, ?string $dateTo): void
  485.     {
  486.         // 🔸 Filtre par numéro de NanoGrid
  487.         if ($nanoReseau !== '') {
  488.             $qb->andWhere('CAST(n.networkNumber AS TEXT) LIKE :nanoReseau')
  489.                 ->setParameter('nanoReseau''%' $nanoReseau '%');
  490.         }
  491.         // 🔸 Filtre par entrepreneur (nom complet)
  492.         if ($nanoEntrepreneur !== '') {
  493.             $qb->andWhere('LOWER(CONCAT(o.firstname, \' \', o.lastname)) LIKE :entrepreneur')
  494.                 ->setParameter('entrepreneur''%' mb_strtolower($nanoEntrepreneur) . '%');
  495.         }
  496.         // 🔸 Filtre par district - CORRIGÉ pour matcher "Zone XXXX"
  497.         if ($district !== '') {
  498.             $decodedDistrict urldecode($district);
  499.             // Si le district commence par "District ", on le remplace par "Zone "
  500.             $searchTerm $decodedDistrict;
  501.             if (str_starts_with($searchTerm'District ')) {
  502.                 $searchTerm str_replace('District ''Zone '$searchTerm);
  503.             }
  504.             if (is_numeric($searchTerm)) {
  505.                 $qb->andWhere('z.id = :districtId')
  506.                     ->setParameter('districtId', (int)$searchTerm);
  507.             } else {
  508.                 // Recherche partielle sur le nom complet de la zone
  509.                 $qb->andWhere('LOWER(z.name) LIKE :districtName')
  510.                     ->setParameter('districtName''%' strtolower($searchTerm) . '%');
  511.             }
  512.         }
  513.         // 🔸 Filtre par période
  514.         if ($dateFrom && $dateTo) {
  515.             $from = \DateTime::createFromFormat('d/m/Y'$dateFrom);
  516.             $to = \DateTime::createFromFormat('d/m/Y'$dateTo);
  517.             if ($from && $to) {
  518.                 $to->setTime(235959);
  519.                 $qb->andWhere('n.dateStartService BETWEEN :from AND :to')
  520.                     ->setParameter('from'$from)
  521.                     ->setParameter('to'$to);
  522.             }
  523.         }
  524.     }
  525.     /**
  526.      * @param Network $network
  527.      * @param EntityManager $em
  528.      * @param Request $request
  529.      * @return Response
  530.      * @throws \Doctrine\ORM\ORMException
  531.      * @throws \Doctrine\ORM\OptimisticLockException
  532.      */
  533.     public function commissionEditAction(Network $networkEntityManager $emRequest $requestLoggerInterface $loggerTranslatorInterface $translatorInterface)
  534.     {
  535.         $form $this->createForm(CommissionNanoEntrepreneurFormType::class, $network);
  536.         $form->handleRequest($request);
  537.         if ($form->isSubmitted() && $form->isValid()) {
  538.             /*$uow = $em->getUnitOfWork();
  539.             $uow->computeChangeSets();*/
  540.             foreach ($network->getNanoEntrepreneurs() as $nanoEntrepreneur) {
  541.                 $this->oNetworkManager->updateTransactionRecordsNanoEntrepreneur($nanoEntrepreneur$em);
  542.             }
  543.             foreach ($network->getCommissionEntrepreneurs() as $commission) {
  544.                 $this->oNetworkManager->updateTransactionRecordsCommission($commission$em);
  545.             }
  546.             try {
  547.                 /** @var Customer $customer */
  548.                 foreach ($network->getCustomers() as $customer) {
  549.                     $customer->setCreator($network->getOwner());
  550.                 }
  551.                 $em->flush();
  552.                 $this->addFlash('success'$translatorInterface->trans('Successful change of commission'));
  553.                 return $this->redirectToRoute('app.commission.list');
  554.             } catch (\Exception $e) {
  555.                 $this->addFlash('error'$translatorInterface->trans('An error occurred, please try again'));
  556.                 $logger->error($e->getMessage(), [__CLASS__ => __FUNCTION__]);
  557.             }
  558.         }
  559.         return $this->render('@App/Network/commissionForm.html.twig', [
  560.             'pageTitle' => $translatorInterface->trans('Change of commission and nano-entrepreneur'),
  561.             'network' => $network,
  562.             'commissionForm' => $form->createView(),
  563.         ]);
  564.     }
  565.     /**
  566.      * @param Request $request
  567.      * @param EntityManager $em
  568.      * @param Network $network
  569.      * @param LoggerInterface $logger
  570.      * @param TranslatorInterface $translatorInterface
  571.      * @return JsonResponse
  572.      * @throws \Doctrine\ORM\ORMException
  573.      * @throws \Doctrine\ORM\OptimisticLockException
  574.      */
  575.     public function deleteAction(
  576.         Request $request,
  577.         EntityManagerInterface $em,
  578.         Network $network,
  579.         LoggerInterface $logger,
  580.         TranslatorInterface $translatorInterface
  581.     ) {
  582.         if (!$this->isGranted(RoleManager::ROLE_ADMIN$this->getUser())) {
  583.             return new JsonResponse([
  584.                 'status' => 'Error',
  585.                 'message' => $translatorInterface->trans('Access refused'),
  586.             ], 403);
  587.         }
  588.         $data $request->request->get('data');
  589.         $data json_decode($datatrue);
  590.         if (json_last_error() !== JSON_ERROR_NONE || !is_array($data) || empty($data)) {
  591.             return new JsonResponse([
  592.                 'status' => 'KO',
  593.                 'message' => 'JSON invalide ou vide'
  594.             ], 400);
  595.         }
  596.         // Construction des données à retourner ou utiliser
  597.         $nanoEntrepreneurs '';
  598.         if (!empty($network->getNanoEntrepreneurs())) {
  599.             $nanoEntrepreneurs $network->getNanoEntrepreneurs()[0]->getOwner()->getFirstname() . ' ' $network->getNanoEntrepreneurs()[0]->getOwner()->getLastName();
  600.         } else {
  601.             $nanoEntrepreneurs $network->getOwner()->getFirstname() . ' ' $network->getOwner()->getLastName();
  602.         }
  603.         $devices = [];
  604.         foreach ($network->getDevices() as $device) {
  605.             if (empty($device->getUserDelete())) {
  606.                 $devices[] = [
  607.                     'name' => $device->getDevice()->getName(),
  608.                     'deviceCount' => $device->getDeviceCount(),
  609.                 ];
  610.             }
  611.         }
  612.         $dataToUse = [
  613.             'networkNumber' => $network->getNetworkNumber(),
  614.             'devices' => $devices,
  615.             'zone' => $network->getZone(),
  616.             'nanoEntrepreneurs' => $nanoEntrepreneurs,
  617.             'dateStartService' => $network->getDateStartService(),
  618.         ];
  619.         try {
  620.             $aAllCustomers $network->getCustomers()->toArray();
  621.             $firstItem $data[0] ?? [
  622.                 "datesup" => null,
  623.                 "comment" => null,
  624.             ];
  625.             $extraData = [
  626.                 'dateUninstall' => $firstItem['datesup'] ?? null,
  627.                 'comment' => $firstItem['comment'] ?? null,
  628.             ];
  629.             $this->oNetworkManager->createHistoricDeletion($network$extraData$dataToUse);
  630.             $em->remove($network);
  631.             $em->flush();
  632.             $this->disableCustomerNetwork($aAllCustomers);
  633.         } catch (\Exception $e) {
  634.             $logger->error($e->getMessage(), [__CLASS__ => __FUNCTION__]);
  635.             return new JsonResponse([
  636.                 'status' => 'KO',
  637.                 'message' => $e->getMessage()
  638.             ], 400);
  639.         }
  640.         return new JsonResponse([
  641.             'status' => 'OK'
  642.         ], 200);
  643.     }
  644.     public function disableCustomerNetwork($aAllCustomers)
  645.     {
  646.         foreach ($aAllCustomers as $oCustomer) {
  647.             try {
  648.                 $oCustomer->setNetwork(null);
  649.                 $oCustomer->setSlotNumber(null);
  650.                 $oCustomer->setStatus(Customer::STATUS_PROSPECT);
  651.                 $oCustomer->setDateJoinNetwork(null);
  652.                 $oCustomer->setCustomNumber(null);
  653.                 $oCustomer->setDateRemoveFromNetwork(new \DateTime());
  654.                 $this->_em->persist($oCustomer);
  655.                 $this->_em->flush();
  656.                 $this->oSynchroOdoo->disabledClient($oCustomer);
  657.             } catch (\Exception $e) {
  658.             }
  659.         };
  660.     }
  661.     public function updateCustomersThatNetworkDeleted(EntityManager $em)
  662.     {
  663.         $customers $em->getRepository(Network::class)->findCustomersWithDeletedNetworks('2019-01-01');
  664.         foreach ($customers as $customer) {
  665.             $customer $em->getRepository(Customer::class)->find($customer['id']);
  666.             $customer->setNetwork(null);
  667.             $customer->setSlotNumber(null);
  668.             $em->persist($customer);
  669.             $em->flush();
  670.         }
  671.         return (count($customers));
  672.     }
  673.     /**
  674.      * @param EntityManager $em
  675.      * @param Device $customer
  676.      * @param Network $network
  677.      * @return JsonResponse
  678.      */
  679.     public function removeDeviceAction(EntityManager $emRequest $requestTranslatorInterface $translatorInterface)
  680.     {
  681.         $dateDeletion $request->get('dateDeletion');
  682.         $motif $request->get('motif');
  683.         $deviceNetworkId $request->get('deviceNetworkId');
  684.         try {
  685.             if (!$motif) {
  686.                 throw new \Exception("Le motif est obligatoire");
  687.             }
  688.             $networkDevice $em->getRepository(NetworkDevice::class)
  689.                 ->find($deviceNetworkId);
  690.             $networkDevice->setDateDeletion(new \DateTime($dateDeletion));
  691.             $networkDevice->setDateRealDeletion(new \DateTime());
  692.             $networkDevice->setMotifDeletion(NetworkDevice::DEVICE_DELETION_MOTIF[$motif]);
  693.             $networkDevice->setUserDelete($this->getUser());
  694.             //$networkDevice->setDevice(null);
  695.             //$em->persist($networkDevice);
  696.             $em->flush();
  697.             $toReturn = [
  698.                 'status' => 'ok',
  699.                 'message' => $translatorInterface->trans('the material was successfully removed'),
  700.             ];
  701.         } catch (\Exception $e) {
  702.             $toReturn = [
  703.                 'status' => 'ko',
  704.                 'message' => $translatorInterface->trans('An error occurred, please try again')
  705.             ];
  706.         }
  707.         return new JsonResponse($toReturn);
  708.     }
  709.     /**
  710.      * @param EntityManager $em
  711.      * @param Device $customer
  712.      * @param Network $network
  713.      * @return JsonResponse
  714.      */
  715.     public function addDeviceAction(EntityManager $emRequest $requestTranslatorInterface $translatorInterface)
  716.     {
  717.         try {
  718.             if (is_array($data $request->get('data'))) {
  719.                 foreach ($data as $aDevice) {
  720.                     $dateCreation = \DateTime::createFromFormat('Y-m-d'$aDevice['dateCreation']);
  721.                     $device $em->getRepository(Device::class)
  722.                         ->findOneBy([
  723.                             'id' => (int) $aDevice['deviceId']
  724.                         ]);
  725.                     $network $em->getRepository(Network::class)
  726.                         ->findOneBy([
  727.                             'id' => (int) $aDevice['networkId']
  728.                         ]);
  729.                     $motif $aDevice['motif'] ? $em->getRepository(Motif::class)
  730.                         ->findOneBy([
  731.                             'id' => (int) $aDevice['motif']
  732.                         ]) : null;
  733.                     $networkDevice = new NetworkDevice();
  734.                     $networkDevice->setDevice($device)
  735.                         ->setNetwork($network)
  736.                         ->setDeviceCount((int) $aDevice['deviceCount'])
  737.                         ->setDateCreation(!empty($dateCreation) ? $dateCreation : new \DateTime())
  738.                         ->setUserCreate($this->getUser());
  739.                     if ($motif) {
  740.                         $networkDevice->setMotif($motif);
  741.                     }
  742.                     $em->persist($networkDevice);
  743.                     $em->flush();
  744.                     $toReturn = [
  745.                         'status' => 200,
  746.                         'message' => $translatorInterface->trans('the material has been added successfully'),
  747.                     ];
  748.                 }
  749.             }
  750.         } catch (\Exception $e) {
  751.             $toReturn = [
  752.                 'status' => 400,
  753.                 'message' => $translatorInterface->trans('An error occurred, please try again')
  754.             ];
  755.         }
  756.         return new JsonResponse($toReturn);
  757.     }
  758.     public function getAllEntrepreneurAction(EntityManager $em)
  759.     {
  760.         $aReturn = [];
  761.         $aResponse = [];
  762.         $aoEntrepreneur $em->getRepository('App\Entity\Users')->getAllEntrepreneurs();
  763.         foreach ($aoEntrepreneur as $entrepreneur) {
  764.             $aReturn['id'] = $entrepreneur->getId();
  765.             $aReturn['firstname'] = $entrepreneur->getFirstname();
  766.             $aReturn['lastname'] = $entrepreneur->getLastname();
  767.             $aResponse[] = $aReturn;
  768.         }
  769.         return new JsonResponse($aResponse);
  770.     }
  771.     public function getServiceAction(Network $network)
  772.     {
  773.         $data $network->getDateStartService();
  774.         return new JsonResponse($data->format("Y-m-d"));
  775.     }
  776.     public function updateNanoentrepreneurCommissionAction(EntityManager $em)
  777.     {
  778.         $aNetwork $em->getRepository('App\Entity\Network')->getNoArrayNC();
  779.         foreach ($aNetwork as $oNetwork) {
  780.             $param['commissions'] = array(
  781.                 'startDate' => $oNetwork->getDateStartService(),
  782.                 'endDate' => null,
  783.                 'commission' => $oNetwork->getCommissionPercentage()
  784.             );
  785.             $param['nanoEntrepreneur'] = array(
  786.                 'startDate' => $oNetwork->getDateStartService(),
  787.                 'endDate' => null,
  788.                 'owner' => $oNetwork->getOwner()->getId()
  789.             );
  790.             $param['id'] = $oNetwork->getId();
  791.             $em->getRepository('App\Entity\Network')->updateNanoentrepreneurCommission($param);
  792.         }
  793.         return new Response("ok");
  794.     }
  795.     public function migrationNanoEntrepreneurCommissionFromArrayToEntityAction(EntityManager $em)
  796.     {
  797.         $aNetwork $em->getRepository('App\Entity\Network')->findAll();
  798.         foreach ($aNetwork as $oNetwork) {
  799.             $commissions $oNetwork->getCommissions();
  800.             $nanoEntrepreneurs $oNetwork->getNanoEntrepreneur();
  801.             $commissionE $em->getRepository("App\Entity\Commission")->findOneByNetwork($oNetwork);
  802.             $nanoEntrepreneurE $em->getRepository("App\Entity\NanoEntrepreneur")->findOneByNetwork($oNetwork);
  803.             if (count($commissions) > && !$commissionE) {
  804.                 foreach ($commissions as $commission) {
  805.                     $oCommission = new Commission();
  806.                     $oCommission->setStartDate($commission['startDate'] === null $oNetwork->getDateCreation() : $commission['startDate']);
  807.                     $oCommission->setEndDate($commission['endDate']);
  808.                     $oCommission->setCommission($commission['commission'] !== null $commission['commission'] : 0);
  809.                     $oCommission->setNetwork($oNetwork);
  810.                     $em->persist($oCommission);
  811.                 }
  812.             }
  813.             if (count($nanoEntrepreneurs) > && !$nanoEntrepreneurE) {
  814.                 foreach ($nanoEntrepreneurs as $nanoEntrepreneur) {
  815.                     $oNanoEntrepreneur = new NanoEntrepreneur();
  816.                     $oNanoEntrepreneur->setStartDate($nanoEntrepreneur['startDate'] === null $oNetwork->getDateCreation() : $nanoEntrepreneur['startDate']);
  817.                     $oNanoEntrepreneur->setEndDate($nanoEntrepreneur['endDate']);
  818.                     $oNanoEntrepreneur->setOwner($em->getRepository('App\Entity\Users')->findOneById($nanoEntrepreneur['owner']));
  819.                     $oNanoEntrepreneur->setNetwork($oNetwork);
  820.                     $em->persist($oNanoEntrepreneur);
  821.                 }
  822.             }
  823.         }
  824.         $em->flush();
  825.         return new Response("ok");
  826.     }
  827.     /**
  828.      * @param EntityManager $em
  829.      * @throws \Doctrine\ORM\ORMException
  830.      * @throws \Doctrine\ORM\OptimisticLockException
  831.      */
  832.     public function historicDeletedNetworkAction(Request $request)
  833.     {
  834.         $params['action'] = 'remove';
  835.         $this->setAccessZoneParams($params);
  836.         $networkHistorics $this->getDoctrine()->getRepository(NetworkHistoric::class)
  837.             ->getNetworkDeleteHistoricByuserzone($params);
  838.         $allDistrict $this->getDoctrine()->getRepository("App\Entity\Zone")->getDistrict();
  839.         return $this->render('Network/historicDeletion.html.twig', [
  840.             'networkHistorics' => $networkHistorics,
  841.             "districts" => $allDistrict
  842.         ]);
  843.     }
  844.     public function generateExcelNetworkAction(Request $request)
  845.     {
  846.         $queryParams $this->requestParamsManager->initQueryParams($request);
  847.         $queryParams['status'] = Network::STATUS_NETWORK;
  848.         $networks $this->_em->getRepository(Network::class)->searchQuery($queryParams)->getQuery()->getResult();
  849.         $spreadsheet = new Spreadsheet();
  850.         $sheet $spreadsheet->getActiveSheet();
  851.         $sheet->setTitle("Liste nano-réseaux");
  852.         $i 1;
  853.         $sheet->setCellValue('A' $i"Nano-Réseau")->getStyle('A1')->getFont()->setBold(true);
  854.         $sheet->setCellValue('B' $i"Zone")->getStyle('B1')->getFont()->setBold(true);
  855.         $sheet->setCellValue('C' $i"District")->getStyle('C1')->getFont()->setBold(true);
  856.         $sheet->setCellValue('D' $i"Nano-Entrepreneur")->getStyle('D1')->getFont()->setBold(true);
  857.         $sheet->setCellValue('E' $i"Nombre de clients")->getStyle('E1')->getFont()->setBold(true);
  858.         $sheet->setCellValue('F' $i"Clients")->getStyle('F1')->getFont()->setBold(true);
  859.         $sheet->setCellValue('G' $i"Matériels")->getStyle('G1')->getFont()->setBold(true);
  860.         $sheet->setCellValue('H' $i"Puissance (W)")->getStyle('H1')->getFont()->setBold(true);
  861.         $sheet->setCellValue('I' $i"Capacité de stockage (Ah)")->getStyle('I1')->getFont()->setBold(true);
  862.         $sheet->setCellValue('J' $i"Tension (V)")->getStyle('J1')->getFont()->setBold(true);
  863.         $sheet->setCellValue('K' $i"Date de mise en service")->getStyle('K1')->getFont()->setBold(true);
  864.         $sheet->setCellValue('L' $i"Date de la dernière maintenance")->getStyle('L1')->getFont()->setBold(true);
  865.         $sheet->setCellValue('M' $i"Date de la dernière relève")->getStyle('M1')->getFont()->setBold(true);
  866.         foreach ($networks as $network) {
  867.             $i++;
  868.             $CustomersString null;
  869.             $DevicesString null;
  870.             $district 'N/A';
  871.             if ($network->getZone()) {
  872.                 $district $network->getZone();
  873.                 for ($j 0$j 4$j++) {
  874.                     $district $district->getParent();
  875.                     if ($district->getLevel() === 2)
  876.                         break;
  877.                 }
  878.             }
  879.             foreach ($customers $network->getCustomers() as $customer) {
  880.                 $CustomersString .= $customer->getCustomNumber() . ' - ' $customer->getFirstname() . ' - ' $customer->getOffer()->getTitle() . ' | ';
  881.             }
  882.             foreach ($devices $network->getDevices() as $device) {
  883.                 if (!$device->getUserDelete()) {
  884.                     $DevicesString .= $device->getDevice()->getName() . ' - ' $device->getDeviceCount() . ' | ';
  885.                 }
  886.             }
  887.             $sheet->setCellValue('A' $i$network->getNetworkNumber());
  888.             $sheet->setCellValue('B' $i$network->getZone()->getName());
  889.             $sheet->setCellValue('C' $i$district);
  890.             $currentDate = new \DateTime();
  891.             // foreach ($network->getNanoEntrepreneurs() as $nanoEntrepreneur) {
  892.             //     if ($currentDate->format('Y-m-d') >= $nanoEntrepreneur->getStartDate()->format('Y-m-d')
  893.             //         && ($nanoEntrepreneur->getEndDate() == null || $currentDate->format('Y-m-d') <= $nanoEntrepreneur->getEndDate()->format('Y-m-d'))) {
  894.             //         $sheet->setCellValue('D'.$i, $nanoEntrepreneur->getOwner()->getFirstname()." ".$nanoEntrepreneur->getOwner()->getLastname());
  895.             //         break;
  896.             //     }
  897.             //     $sheet->setCellValue('D'.$i, $network->getOwner()->getFirstname().' '.$network->getOwner()->getLastname());
  898.             //     break;
  899.             // }
  900.             $nanoEntrepreneurName '';
  901.             if (!empty($network->getNanoEntrepreneurs()) && !is_null($network->getNanoEntrepreneurs()[0])) {
  902.                 $nanoEntrepreneurName $network->getNanoEntrepreneurs()[0]->getOwner()->getFirstname() . " " $network->getNanoEntrepreneurs()[0]->getOwner()->getLastname();
  903.             } else {
  904.                 $nanoEntrepreneurName $network->getOwner()->getFirstname() . " " $network->getOwner()->getLastName();
  905.             }
  906.             $sheet->setCellValue('D' $i$nanoEntrepreneurName);
  907.             $sheet->setCellValue('E' $icount($customers));
  908.             $sheet->setCellValue('F' $i$CustomersString);
  909.             $sheet->setCellValue('G' $i$DevicesString);
  910.             $sheet->setCellValue('H' $i$network->getPuissance($devices));
  911.             $sheet->setCellValue('I' $i$network->getCapaciteStockage($devices));
  912.             $sheet->setCellValue('J' $i$network->getTotalvoltage());
  913.             $dateStartService null;
  914.             if (!is_null($network->getDateStartService())) {
  915.                 $dateStartService $network->getDateStartService();
  916.                 $sheet->setCellValue('K' $i, \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($network->getDateStartService()->format('d/m/Y')))
  917.                     ->getStyle('K' $i)
  918.                     ->getNumberFormat()
  919.                     ->setFormatCode('dd/mm/yyyy');
  920.             }
  921.             $sheet->setCellValue('L' $i$network->getInterventions()[0] && $network->getInterventions()[0]->getType() == Task::TYPE_MAINTENANCE ?
  922.                 \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($network->getInterventions()[0]->getDateIntervention()) : '')
  923.                 ->getStyle('L' $i)
  924.                 ->getNumberFormat()
  925.                 ->setFormatCode('dd/mm/yyyy');
  926.             $sheet->setCellValue('M' $i$network->getInterventions()[0] && $network->getInterventions()[0]->getType() == Task::TYPE_RECORD ?
  927.                 \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($network->getInterventions()[0]->getDateIntervention()) : '')
  928.                 ->getStyle('M' $i)
  929.                 ->getNumberFormat()
  930.                 ->setFormatCode('dd/mm/yyyy');
  931.             $this->_em->detach($network);
  932.         }
  933.         $writer = new Xlsx($spreadsheet);
  934.         $response = new StreamedResponse(
  935.             function () use ($writer) {
  936.                 $writer->save('php://output');
  937.             }
  938.         );
  939.         $dispositionHeader $response->headers->makeDisposition(
  940.             ResponseHeaderBag::DISPOSITION_ATTACHMENT,
  941.             'PhpExcelFileSample.xls'
  942.         );
  943.         foreach (range('A''M') as $columnID) {
  944.             $sheet->getColumnDimension($columnID)
  945.                 ->setAutoSize(true);
  946.         }
  947.         $response->headers->set('Content-Type''text/vnd.ms-excel; charset=utf-8');
  948.         $response->headers->set('Pragma''public');
  949.         $response->headers->set('Cache-Control''maxage=1');
  950.         $response->headers->set('Content-Disposition'$dispositionHeader);
  951.         return $response;
  952.     }
  953.     public function generatePdfNetworkAction(Request $requestPdf $pdf)
  954.     {
  955.         $queryParams $this->requestParamsManager->initQueryParams($request);
  956.         $queryParams['status'] = Network::STATUS_NETWORK;
  957.         $networks $this->_em->getRepository(Network::class)->searchQuery($queryParams)->getQuery()->getResult();
  958.         $network $this->renderView(
  959.             '@App/Network/pdf.html.twig',
  960.             [
  961.                 'networks' => $networks,
  962.                 'pageTitle' => 'Liste Nano-' $translatorInterface->trans('Grid'),
  963.             ]
  964.         );
  965.         $snappy $pdf;
  966.         $filename 'Liste_nano-réseaux_' . (new \DateTime('now'))->format('YmdHi');
  967.         return new Response(
  968.             $snappy->getOutputFromHtml(
  969.                 $network,
  970.                 array(
  971.                     'encoding' => 'utf-8',
  972.                 )
  973.             ),
  974.             200,
  975.             array(
  976.                 'Content-Type' => 'application/pdf',
  977.                 'Content-Disposition' => 'inline; filename="' $filename '.pdf"'
  978.             )
  979.         );
  980.     }
  981.     public function generateCsvNetworkAction(Request $requestTranslatorInterface $translatorInterface)
  982.     {
  983.         $queryParams $this->requestParamsManager->initQueryParams($request);
  984.         $queryParams['status'] = Network::STATUS_NETWORK;
  985.         $networks $this->_em->getRepository(Network::class)->searchQuery($queryParams)->getQuery()->getResult();
  986.         $fileName "statistiques_clients" . (new \DateTime('now'))->format('YmdHi') . ".csv";
  987.         $response = new StreamedResponse();
  988.         $response->setCallback(function () use ($networks$translatorInterface) {
  989.             $handle fopen('php://output''w+');
  990.             $aTitle = array(
  991.                 $translatorInterface->trans('Number of Nano-Network'),
  992.                 'Zone',
  993.                 'District',
  994.                 'Nano-Entrepreneur',
  995.                 $translatorInterface->trans('Number of Customer'),
  996.                 $translatorInterface->trans('Customers'),
  997.                 $translatorInterface->trans('Equipments'),
  998.                 $translatorInterface->trans('Power') . ' (W)',
  999.                 $translatorInterface->trans('Storage capacity') . ' (Ah)',
  1000.                 $translatorInterface->trans('Voltage') . ' (V)',
  1001.                 $translatorInterface->trans('Commissioning date'),
  1002.                 $translatorInterface->trans('Last maintenance date'),
  1003.                 $translatorInterface->trans('Last Data collection')
  1004.             );
  1005.             $aTitle array_map("utf8_decode"$aTitle);
  1006.             fputcsv($handle$aTitle';');
  1007.             $currentDate = new \DateTime();
  1008.             foreach ($networks as $index => $network) {
  1009.                 $district 'N/A';
  1010.                 if ($network->getZone()) {
  1011.                     $district $network->getZone();
  1012.                     for ($j 0$j 4$j++) {
  1013.                         $district $district->getParent();
  1014.                         if ($district->getLevel() === 2)
  1015.                             break;
  1016.                     }
  1017.                 }
  1018.                 // foreach ($network->getNanoEntrepreneurs() as $nanoEntrepreneur) {
  1019.                 //     if ($currentDate->format('Y-m-d') >= $nanoEntrepreneur->getStartDate()->format('Y-m-d')
  1020.                 //         && ($nanoEntrepreneur->getEndDate() == null || $currentDate->format('Y-m-d') <= $nanoEntrepreneur->getEndDate()->format('Y-m-d'))) {
  1021.                 //         $entrepreneur = $nanoEntrepreneur->getOwner()->getFirstname();
  1022.                 //         break;
  1023.                 //     }
  1024.                 //     $entrepreneur = $network->getCustomers()->getNetwork()->getOwner()->getFirstname();
  1025.                 //     break;
  1026.                 // }
  1027.                 $entrepreneur '';
  1028.                 if (!empty($network->getNanoEntrepreneurs()) && !is_null($network->getNanoEntrepreneurs()[0])) {
  1029.                     $entrepreneur $network->getNanoEntrepreneurs()[0]->getOwner()->getFirstname() . " " $network->getNanoEntrepreneurs()[0]->getOwner()->getLastname();
  1030.                 } else {
  1031.                     $entrepreneur $network->getOwner()->getFirstname() . " " $network->getOwner()->getLastName();
  1032.                 }
  1033.                 $CustomersString null;
  1034.                 $DevicesString null;
  1035.                 foreach ($customers $network->getCustomers() as $customer) {
  1036.                     $CustomersString .= $customer->getCustomNumber() . ' - ' $customer->getFirstname() . ' - ' $customer->getOffer()->getTitle() . ' | ';
  1037.                 }
  1038.                 foreach ($devices $network->getDevices() as $device) {
  1039.                     if (!$device->getUserDelete()) {
  1040.                         $DevicesString .= $device->getDevice()->getName() . ' - ' $device->getDeviceCount() . ' | ';
  1041.                     }
  1042.                 }
  1043.                 $dateStartService null;
  1044.                 if ($network->getDateStartService()) {
  1045.                     $dateStartService $network->getDateStartService()->format('d/m/Y');
  1046.                 }
  1047.                 // $entrepreneur = $network->getCustomers()->getNetwork()->getOwner()->getFirstname();
  1048.                 $aBody = array(
  1049.                     $network->getNetworkNumber(),
  1050.                     $network->getZone()->getName(),
  1051.                     $district,
  1052.                     $entrepreneur//$entrepreneur
  1053.                     count($customers),
  1054.                     $CustomersString,
  1055.                     $DevicesString,
  1056.                     $network->getPuissance($devices),
  1057.                     $network->getCapaciteStockage($devices),
  1058.                     $network->getTotalvoltage(),
  1059.                     $dateStartService,
  1060.                     $network->getInterventions()[0] && $network->getInterventions()[0]->getType() == Task::TYPE_MAINTENANCE ?
  1061.                         $network->getInterventions()[0]->getDateIntervention()->format('d/m/Y') : '',
  1062.                     $network->getInterventions()[0] && $network->getInterventions()[0]->getType() == Task::TYPE_RECORD ?
  1063.                         $network->getInterventions()[0]->getDateIntervention()->format('d/m/Y') : ''
  1064.                 );
  1065.                 $aBody array_map("utf8_decode"$aBody);
  1066.                 fputcsv($handle$aBody';');
  1067.                 $this->_em->detach($network);
  1068.             }
  1069.             fclose($handle);
  1070.         });
  1071.         $response->setStatusCode(200);
  1072.         $response->headers->set('Content-Type''text/csv; charset=utf-8''application/force-download');
  1073.         $response->headers->set('Content-Disposition''attachment; filename=' $fileName);
  1074.         return $response;
  1075.     }
  1076.     /**
  1077.      * @param Request $request
  1078.      * @param EntityManagerInterface $em
  1079.      * @return JsonResponse|RedirectResponse|Response
  1080.      */
  1081.     public function saveCommentAction(Request $requestEntityManagerInterface $em)
  1082.     {
  1083.         $data json_decode($request->getContent(), true);
  1084.         $networkId $data["network_id"];
  1085.         $userId $data["user_id"];
  1086.         $content $data["content"];
  1087.         $commentData = [];
  1088.         $returnData = [];
  1089.         try {
  1090.             //$network = $em->getRepository('App\Entity\Network')->find($networkId);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ('App\Entity\Customer')->find($customerId);
  1091.             $network $em->getRepository('App\Entity\Network')->find($networkId);
  1092.             $user $em->getRepository('App\Entity\Users')->find($userId);
  1093.             if ($network && $user) {
  1094.                 $networkComment = new NetworkComment();
  1095.                 $networkComment->setOwner($network);
  1096.                 $networkComment->setWriter($user);
  1097.                 $networkComment->setContent($content);
  1098.                 $em->persist($networkComment);
  1099.                 $em->flush();
  1100.             }
  1101.             $commentData $em->getRepository("App\Entity\NetworkComment")
  1102.                 ->findBy(['owner' => $networkId], ['id' => 'DESC']);
  1103.             foreach ($commentData as $comment) {
  1104.                 $returnData[] = [
  1105.                     'owner' => $comment->getOwner()->getId(),
  1106.                     'writer' => [
  1107.                         'id' => $comment->getWriter()->getId(),
  1108.                         'name' => $comment->getWriter()->getFirstname() . ' ' $comment->getWriter()->getLastname()
  1109.                     ],
  1110.                     'content' => $comment->getContent(),
  1111.                     'dateCreation' => $comment->getDateCreation()->format('c'),
  1112.                 ];
  1113.             }
  1114.         } catch (\RuntimeException $exception) {
  1115.             return new JsonResponse([
  1116.                 'status' => 'KO',
  1117.                 'message' => $exception->getMessage()
  1118.             ], $exception->getCode());
  1119.         }
  1120.         return new JsonResponse([
  1121.             'status' => 'OK',
  1122.             'data' => $returnData,
  1123.         ], 200);
  1124.     }
  1125.     /**
  1126.      * @param Request $request
  1127.      * @param EntityManagerInterface $em
  1128.      * @return JsonResponse|RedirectResponse|Response
  1129.      */
  1130.     public function listCommentAction(Request $requestEntityManagerInterface $emNetwork $network)
  1131.     {
  1132.         $commentData $em->getRepository("App\Entity\NetworkComment")
  1133.             ->findBy(['owner' => $network->getId()], ['id' => 'DESC']);
  1134.         $returnData = [];
  1135.         foreach ($commentData as $comment) {
  1136.             $returnData[] = [
  1137.                 'owner' => $comment->getOwner()->getId(),
  1138.                 'writer' => [
  1139.                     'id' => $comment->getWriter()->getId(),
  1140.                     'name' => $comment->getWriter()->getFirstname() . ' ' $comment->getWriter()->getLastname()
  1141.                 ],
  1142.                 'content' => $comment->getContent(),
  1143.                 'dateCreation' => $comment->getDateCreation()->format('c'),
  1144.             ];
  1145.         }
  1146.         return new JsonResponse([
  1147.             'status' => 'OK',
  1148.             'data' => $returnData,
  1149.         ], 200);
  1150.     }
  1151.     public function export(Request $requestEntityManagerInterface $entityManager): Response
  1152.     {
  1153.         $this->denyAccessUnlessGranted(RoleManager::ROLE_ENTREPRENEUR$this->getUser());
  1154.         $format $request->query->get('format''csv');
  1155.         // Récupération simple de tous les réseaux
  1156.         $networks $entityManager->getRepository(Network::class)
  1157.             ->findAll();
  1158.         $records = [];
  1159.         foreach ($networks as $network) {
  1160.             $owner $network->getOwner();
  1161.             $records[] = [
  1162.                 'networkId' => $network->getId(),
  1163.                 'networkNumber' => $network->getNetworkNumber(),
  1164.                 'owner' => $owner $owner->getFirstname() . ' ' $owner->getLastname() : 'N/A',
  1165.                 'entrepreneurStartDate' => $network->getDateStartService(),
  1166.                 'entrepreneurEndDate' => 'actif',
  1167.                 'commissionStartDate' => $network->getDateStartService(),
  1168.                 'commissionEndDate' => 'actif',
  1169.                 'commission' => $network->getCommissionPercentage(),
  1170.                 'zone' => $network->getZone(),
  1171.                 'district' => $this->getDistrictName($network->getZone())
  1172.             ];
  1173.         }
  1174.         // Si toujours vide, utilisez les données de test
  1175.         if (empty($records)) {
  1176.             $records $this->getTestData();
  1177.         }
  1178.         switch ($format) {
  1179.             case 'xlsx':
  1180.                 return $this->exportExcel($records);
  1181.             case 'pdf':
  1182.                 return $this->exportPdf($records);
  1183.             default:
  1184.                 return $this->exportCsv($records);
  1185.         }
  1186.     }
  1187.     private function getDistrictName($zone)
  1188.     {
  1189.         if (!$zone) {
  1190.             return 'N/A';
  1191.         }
  1192.         $currentZone $zone;
  1193.         for ($i 0$i 6$i++) {
  1194.             if ($currentZone && $currentZone->getLevel() == 2) {
  1195.                 return $currentZone->getName();
  1196.             }
  1197.             if ($currentZone && $currentZone->getParent()) {
  1198.                 $currentZone $currentZone->getParent();
  1199.             } else {
  1200.                 break;
  1201.             }
  1202.         }
  1203.         return 'N/A';
  1204.     }
  1205.     private function exportCsv(array $records): Response
  1206.     {
  1207.         $response = new StreamedResponse(function () use ($records) {
  1208.             $handle fopen('php://output''w+');
  1209.             // Optional BOM for Excel/Excel-like programs:
  1210.             // fwrite($handle, "\xEF\xBB\xBF");
  1211.             fputcsv($handle, [
  1212.                 'Numéro NanoGrid',
  1213.                 'Nano-Entrepreneur',
  1214.                 'District',
  1215.                 'Date début Nano-Entrepreneur',
  1216.                 'Date fin Nano-Entrepreneur',
  1217.                 'Commission (%)',
  1218.                 'Date début commission',
  1219.                 'Date fin commission'
  1220.             ], ';');
  1221.             foreach ($records as $record) {
  1222.                 fputcsv($handle, [
  1223.                     $record['networkNumber'] ?? '',
  1224.                     $record['owner'] ?? '',
  1225.                     $record['district'] ?? '',
  1226.                     ($record['entrepreneurStartDate'] ?? null) instanceof \DateTime $record['entrepreneurStartDate']->format('d/m/Y') : '',
  1227.                     ($record['entrepreneurEndDate'] ?? '') == 'actif' 'Actif' : (($record['entrepreneurEndDate'] ?? null) instanceof \DateTime $record['entrepreneurEndDate']->format('d/m/Y') : ''),
  1228.                     $record['commission'] ?? '',
  1229.                     ($record['commissionStartDate'] ?? null) instanceof \DateTime $record['commissionStartDate']->format('d/m/Y') : '',
  1230.                     ($record['commissionEndDate'] ?? '') == 'actif' 'Actif' : (($record['commissionEndDate'] ?? null) instanceof \DateTime $record['commissionEndDate']->format('d/m/Y') : '')
  1231.                 ], ';');
  1232.             }
  1233.             fclose($handle);
  1234.         });
  1235.         $disposition $response->headers->makeDisposition(
  1236.             ResponseHeaderBag::DISPOSITION_ATTACHMENT,
  1237.             'commissions.csv'
  1238.         );
  1239.         $response->headers->set('Content-Type''text/csv; charset=utf-8');
  1240.         $response->headers->set('Content-Disposition'$disposition);
  1241.         return $response;
  1242.     }
  1243.     private function exportExcel(array $records): Response
  1244.     {
  1245.         $spreadsheet = new Spreadsheet();
  1246.         $sheet $spreadsheet->getActiveSheet();
  1247.         $headers = [
  1248.             'Numéro NanoGrid',
  1249.             'Nano-Entrepreneur',
  1250.             'District',
  1251.             'Date début Nano-Entrepreneur',
  1252.             'Date fin Nano-Entrepreneur',
  1253.             'Commission (%)',
  1254.             'Date début commission',
  1255.             'Date fin commission'
  1256.         ];
  1257.         $sheet->fromArray([$headers], null'A1');
  1258.         $row 2;
  1259.         foreach ($records as $record) {
  1260.             $sheet->fromArray([[
  1261.                 $record['networkNumber'] ?? '',
  1262.                 $record['owner'] ?? '',
  1263.                 $record['district'] ?? '',
  1264.                 ($record['entrepreneurStartDate'] ?? null) instanceof \DateTime $record['entrepreneurStartDate']->format('d/m/Y') : '',
  1265.                 ($record['entrepreneurEndDate'] ?? '') == 'actif' 'Actif' : (($record['entrepreneurEndDate'] ?? null) instanceof \DateTime $record['entrepreneurEndDate']->format('d/m/Y') : ''),
  1266.                 $record['commission'] ?? '',
  1267.                 ($record['commissionStartDate'] ?? null) instanceof \DateTime $record['commissionStartDate']->format('d/m/Y') : '',
  1268.                 ($record['commissionEndDate'] ?? '') == 'actif' 'Actif' : (($record['commissionEndDate'] ?? null) instanceof \DateTime $record['commissionEndDate']->format('d/m/Y') : '')
  1269.             ]], null'A' $row++);
  1270.         }
  1271.         // Style pour les en-têtes
  1272.         $headerStyle = [
  1273.             'font' => ['bold' => true],
  1274.             'fill' => [
  1275.                 'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
  1276.                 'startColor' => ['argb' => 'FFE6E6FA']
  1277.             ]
  1278.         ];
  1279.         $sheet->getStyle('A1:H1')->applyFromArray($headerStyle);
  1280.         // Auto-size columns
  1281.         foreach (range('A''H') as $column) {
  1282.             $sheet->getColumnDimension($column)->setAutoSize(true);
  1283.         }
  1284.         $writer = new Xlsx($spreadsheet);
  1285.         $response = new StreamedResponse(function () use ($writer) {
  1286.             $writer->save('php://output');
  1287.         });
  1288.         $disposition $response->headers->makeDisposition(
  1289.             ResponseHeaderBag::DISPOSITION_ATTACHMENT,
  1290.             'commissions.xlsx'
  1291.         );
  1292.         $response->headers->set('Content-Type''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  1293.         $response->headers->set('Content-Disposition'$disposition);
  1294.         return $response;
  1295.     }
  1296.     private function exportPdf(array $records): Response
  1297.     {
  1298.         set_time_limit(600);
  1299.         // Limiter les enregistrements pour le PDF
  1300.         if (count($records) > 20000) {
  1301.             $records array_slice($records020000);
  1302.         }
  1303.         $pdf = new \TCPDF('L'PDF_UNITPDF_PAGE_FORMATtrue'UTF-8'false);
  1304.         $pdf->SetCreator('Your App');
  1305.         $pdf->SetAuthor('Your App');
  1306.         $pdf->SetTitle('Liste des Commissions');
  1307.         $pdf->SetSubject('Commissions');
  1308.         $pdf->SetKeywords('commissions, PDF');
  1309.         $pdf->setHeaderFont([PDF_FONT_NAME_MAIN''PDF_FONT_SIZE_MAIN]);
  1310.         $pdf->setFooterFont([PDF_FONT_NAME_DATA''PDF_FONT_SIZE_DATA]);
  1311.         $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
  1312.         $pdf->SetMargins(101510);
  1313.         $pdf->SetHeaderMargin(5);
  1314.         $pdf->SetFooterMargin(10);
  1315.         $pdf->SetAutoPageBreak(true15);
  1316.         $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
  1317.         $pdf->SetFont('helvetica'''8);
  1318.         $pdf->AddPage();
  1319.         // Titre
  1320.         $pdf->SetFont('helvetica''B'12);
  1321.         $pdf->Cell(010'Liste des Commissions'01'C');
  1322.         $pdf->SetFont('helvetica'''8);
  1323.         $pdf->Ln(5);
  1324.         // En-têtes du tableau
  1325.         $headers = ['NG Number''Entrepreneur''District''Début Entrep.''Fin Entrep.''Commission''Début Comm.''Fin Comm.'];
  1326.         // Largeurs des colonnes
  1327.         $widths = [2030252020152020];
  1328.         // En-têtes
  1329.         $pdf->SetFillColor(240240240);
  1330.         $pdf->SetFont('helvetica''B'7);
  1331.         foreach ($headers as $i => $header) {
  1332.             $pdf->Cell($widths[$i], 6$header10'C'true);
  1333.         }
  1334.         $pdf->Ln();
  1335.         // Données
  1336.         $pdf->SetFont('helvetica'''6);
  1337.         $pdf->SetFillColor(255255255);
  1338.         foreach ($records as $record) {
  1339.             $data = [
  1340.                 $record['networkNumber'] ?? '',
  1341.                 $record['owner'] ?? '',
  1342.                 $record['district'] ?? '',
  1343.                 ($record['entrepreneurStartDate'] ?? null) instanceof \DateTime $record['entrepreneurStartDate']->format('d/m/Y') : '',
  1344.                 ($record['entrepreneurEndDate'] ?? '') == 'actif' 'Actif' : (($record['entrepreneurEndDate'] ?? null) instanceof \DateTime $record['entrepreneurEndDate']->format('d/m/Y') : ''),
  1345.                 $record['commission'] ?? '',
  1346.                 ($record['commissionStartDate'] ?? null) instanceof \DateTime $record['commissionStartDate']->format('d/m/Y') : '',
  1347.                 ($record['commissionEndDate'] ?? '') == 'actif' 'Actif' : (($record['commissionEndDate'] ?? null) instanceof \DateTime $record['commissionEndDate']->format('d/m/Y') : '')
  1348.             ];
  1349.             foreach ($data as $i => $value) {
  1350.                 $pdf->Cell($widths[$i], 5$value10'C');
  1351.             }
  1352.             $pdf->Ln();
  1353.             // Ajouter une nouvelle page si nécessaire
  1354.             if ($pdf->GetY() > 180) {
  1355.                 $pdf->AddPage();
  1356.                 // Réafficher les en-têtes
  1357.                 $pdf->SetFont('helvetica''B'7);
  1358.                 foreach ($headers as $i => $header) {
  1359.                     $pdf->Cell($widths[$i], 6$header10'C'true);
  1360.                 }
  1361.                 $pdf->Ln();
  1362.                 $pdf->SetFont('helvetica'''6);
  1363.             }
  1364.         }
  1365.         return new Response($pdf->Output('commissions.pdf''S'), 200, [
  1366.             'Content-Type' => 'application/pdf',
  1367.             'Content-Disposition' => 'attachment; filename="commissions.pdf"'
  1368.         ]);
  1369.     }
  1370. }