src/Controller/EntrepriseController.php line 501

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\CSPE;
  4. use App\Entity\Note;
  5. use App\Entity\User;
  6. use App\Entity\Rappel;
  7. use App\Entity\Contact;
  8. use App\Entity\Contrat;
  9. use App\Entity\GasMeter;
  10. use App\Entity\Entreprise;
  11. use App\Entity\EspaceClient;
  12. use App\Entity\ElectricMeter;
  13. use App\Form\EntrepriseType;
  14. use App\Form\ContratType;
  15. use App\Form\UserEntrepriseType;
  16. use App\Service\PricingService;
  17. use Symfony\Contracts\HttpClient\HttpClientInterface;
  18. use Doctrine\Persistence\ManagerRegistry;
  19. use Doctrine\ORM\EntityManagerInterface;
  20. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpFoundation\Response;
  23. use Symfony\Component\HttpFoundation\JsonResponse;
  24. use Symfony\Component\Routing\Annotation\Route;
  25. use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
  26. use Psr\Log\LoggerInterface;
  27. class EntrepriseController extends AbstractController
  28. {
  29.     private PricingService $pricingService;
  30.     private LoggerInterface $logger;
  31.     public function __construct(PricingService $pricingServiceLoggerInterface $logger)
  32.     {
  33.         $this->pricingService $pricingService;
  34.         $this->logger $logger;
  35.     }
  36.     /**
  37.      * @Route("/entreprise", name="app_entreprise")
  38.      */
  39.     public function index(Request $requestManagerRegistry $doctrine): Response
  40.     {
  41.         $em $doctrine->getManager();
  42.         // ---- FILTRE STATUT (Client | Prospect | null) ----
  43.         $StatutFilter $request->query->get('Statut'); // ex: ?Statut=Client
  44.         // ---- FILTRE CONTRAT (with | without | null) ----
  45.         $ContratFilter $request->query->get('Contrat'); // ex: ?Contrat=with
  46.         $qb $em->createQueryBuilder()
  47.             ->select('e')
  48.             ->from(Entreprise::class, 'e');
  49.         if ($StatutFilter && in_array($StatutFilter, ['Client''Prospect'], true)) {
  50.             $qb->andWhere('e.Statut = :Statut')->setParameter('Statut'$StatutFilter);
  51.         }
  52. $entreprises $qb->getQuery()->getResult();
  53. // IDs AVANT filtrage contrat
  54. $entrepriseIdsAll array_map(fn ($e) => $e->getId(), $entreprises);
  55. // ---- MAP: entreprises qui ont au moins 1 contrat ----
  56. $hasContractEids = [];
  57. if ($entrepriseIdsAll) {
  58.     $rows $em->createQueryBuilder()
  59.         ->select('IDENTITY(c.entreprise) AS eid')
  60.         ->from(Contrat::class, 'c')
  61.         ->where('c.entreprise IN (:ids)')
  62.         ->setParameter('ids'$entrepriseIdsAll)
  63.         ->groupBy('eid')
  64.         ->getQuery()
  65.         ->getArrayResult();
  66.     foreach ($rows as $r) {
  67.         if (!empty($r['eid'])) {
  68.             $hasContractEids[(int) $r['eid']] = true;
  69.         }
  70.     }
  71. }
  72. // ---- Application du filtre Contrat sur la liste d'entreprises ----
  73. if ($ContratFilter === 'with') {
  74.     $entreprises array_values(array_filter($entreprises, fn($e) => isset($hasContractEids[$e->getId()])));
  75. } elseif ($ContratFilter === 'without') {
  76.     $entreprises array_values(array_filter($entreprises, fn($e) => !isset($hasContractEids[$e->getId()])));
  77. }
  78. // IDs finaux (après filtrage)
  79. $entrepriseIds array_map(fn ($e) => $e->getId(), $entreprises);
  80.         // ---- MAP RS (globale) pour CONTRATS/PDL (évite "entreprise supprimée" à tort)
  81.         $allRs $em->createQueryBuilder()
  82.             ->select('e2.id AS id, e2.RaisonSociale AS rs')
  83.             ->from(Entreprise::class, 'e2')
  84.             ->getQuery()->getArrayResult();
  85.         $rsByIdAll = [];
  86.         foreach ($allRs as $row) {
  87.             $rsByIdAll[(int) $row['id']] = $row['rs'];
  88.         }
  89.         // ---- MAP Utilisateurs (pour le tableau entreprises)
  90.         $allUserIds = [];
  91.         foreach ($entreprises as $e) {
  92.             foreach ((array) $e->getUtilisateur() as $uid) {
  93.                 if ($uid !== null && $uid !== '') {
  94.                     $allUserIds[(int) $uid] = true;
  95.                 }
  96.             }
  97.         }
  98.         $allUserIds array_keys($allUserIds);
  99.         $usersById = [];
  100.         if ($allUserIds) {
  101.             $users $em->createQueryBuilder()
  102.                 ->select('u.id, u.username')
  103.                 ->from(User::class, 'u')
  104.                 ->where('u.id IN (:ids)')->setParameter('ids'$allUserIds)
  105.                 ->getQuery()->getArrayResult();
  106.             foreach ($users as $u) {
  107.                 $usersById[(int) $u['id']] = $u['username'];
  108.             }
  109.         }
  110.         // ---- CONTACTS PAR ENTREPRISE (1 requête)
  111.         $contactsByEntreprise = [];
  112.         if ($entrepriseIds) {
  113.             $rows $em->createQueryBuilder()
  114.                 ->select('c.entreprise_id AS eid, c.nom AS nom, c.prenom AS prenom')
  115.                 ->from(Contact::class, 'c')
  116.                 ->where('c.entreprise_id IN (:ids)')->setParameter('ids'$entrepriseIds)
  117.                 ->getQuery()->getArrayResult();
  118.             foreach ($rows as $r) {
  119.                 $eid = (int) $r['eid'];
  120.                 $contactsByEntreprise[$eid][] = trim(($r['nom'] ?? '') . ' ' . ($r['prenom'] ?? ''));
  121.             }
  122.         }
  123.         // ---- COMPTEURS ÉLEC/GAZ PAR ENTREPRISE (2 requêtes)
  124.         $elecByEntreprise $gazByEntreprise = [];
  125.         if ($entrepriseIds) {
  126.             $electricMeters $em->createQueryBuilder()
  127.                 ->select('em.entreprise_id AS eid, em.PDL AS pdl')
  128.                 ->from(ElectricMeter::class, 'em')
  129.                 ->where('em.entreprise_id IN (:ids)')->setParameter('ids'$entrepriseIds)
  130.                 ->getQuery()->getArrayResult();
  131.             foreach ($electricMeters as $r) {
  132.                 $elecByEntreprise[(int) $r['eid']][] = $r['pdl'];
  133.             }
  134.             $gasMeters $em->createQueryBuilder()
  135.                 ->select('gm.entreprise_id AS eid, gm.PDL AS pdl')
  136.                 ->from(GasMeter::class, 'gm')
  137.                 ->where('gm.entreprise_id IN (:ids)')->setParameter('ids'$entrepriseIds)
  138.                 ->getQuery()->getArrayResult();
  139.             foreach ($gasMeters as $r) {
  140.                 $gazByEntreprise[(int) $r['eid']][] = $r['pdl'];
  141.             }
  142.         }
  143.         // ---- TABLEAU ENTREPRISES (affiche uniquement les entreprises filtrées)
  144.         $array_entreprises = [];
  145.         foreach ($entreprises as $e) {
  146.             $eid $e->getId();
  147.             $usernames = [];
  148.             foreach ((array) $e->getUtilisateur() as $uid) {
  149.                 $uid = (int) $uid;
  150.                 if (isset($usersById[$uid])) {
  151.                     $usernames[] = $usersById[$uid];
  152.                 }
  153.             }
  154.             $entreprise_contacts = isset($contactsByEntreprise[$eid]) ? implode(', '$contactsByEntreprise[$eid]) : '';
  155.             $allPdls implode(', 'array_merge($elecByEntreprise[$eid] ?? [], $gazByEntreprise[$eid] ?? []));
  156.             $array_entreprises[] = [
  157.                 $e->getRaisonSociale(),
  158.                 $e->getCommune(),
  159.                 $e->getSiret(),
  160.                 $entreprise_contacts,
  161.                 implode(', '$usernames),
  162.                 '<div class="d-flex justify-content-center gap-2">
  163.                     <a href="' $this->generateUrl('app_entreprise_details', ['id' => $eid]) . '" class="btn btn-sm btn-primary"><i class="fa-solid fa-eye"></i></a>
  164.                     <a href="' $this->generateUrl('app_entreprise_edit', ['id' => $eid]) . '" class="btn btn-sm btn-warning"><i class="fa-solid fa-screwdriver-wrench"></i></a>
  165.                     <a href="' $this->generateUrl('app_entreprise_suppr', ['id' => $eid]) . '" class="btn btn-sm btn-danger"><i class="fa-solid fa-trash"></i></a>
  166.                 </div>',
  167.                 $allPdls,
  168.                 $e->getNaf(),
  169.                 $eid,
  170.             ];
  171.         }
  172.         // =========================================================
  173.         //    CONTRATS – TIMELINE + CONTRACTS_BY_PDL (pour PDL)
  174.         // =========================================================
  175.         /** @var Contrat[] $contrats */
  176.         $contrats $em->getRepository(Contrat::class)->findAll();
  177.         // PDL Elec / Gaz pour repérer les contrats gaz (décalage +1j)
  178.         $electricPDLs array_column(
  179.             $em->createQueryBuilder()->select('em.PDL AS p')->from(ElectricMeter::class, 'em')->getQuery()->getScalarResult(),
  180.             'p'
  181.         );
  182.         $gasPDLs array_column(
  183.             $em->createQueryBuilder()->select('gm.PDL AS p')->from(GasMeter::class, 'gm')->getQuery()->getScalarResult(),
  184.             'p'
  185.         );
  186.         $isGaz array_fill_keys($gasPDLstrue);
  187.         // ---- PDLs (élec/gaz) + liste des contrats par PDL pour les child-rows DataTables
  188.         $allMeterPDLs array_values(array_unique(array_filter(array_merge($electricPDLs$gasPDLs))));
  189.         $contractsByPdl = [];
  190.         if ($allMeterPDLs) {
  191.             $allC $em->createQueryBuilder()
  192.                 ->select('c.id, c.pdl, c.date_debut AS dateDebut, c.date_fin AS dateFin, c.fournisseur, e.id AS eid')
  193.                 ->from(Contrat::class, 'c')
  194.                 ->leftJoin('c.entreprise''e')
  195.                 ->where('c.pdl IN (:pdls)')->setParameter('pdls'$allMeterPDLs)
  196.                 ->orderBy('c.pdl''ASC')
  197.                 ->addOrderBy('c.date_debut''DESC')
  198.                 ->getQuery()->getArrayResult();
  199.             foreach ($allC as $row) {
  200.                 $p = (string) $row['pdl'];
  201.                 $eid $row['eid'] ?? null;
  202.                 $cid = isset($row['id']) ? (int) $row['id'] : null;
  203.                 $contractsByPdl[$p][] = [
  204.                     'id'          => $cid,
  205.                     'entreprise'  => $eid && isset($rsByIdAll[$eid]) ? $rsByIdAll[$eid] : 'entreprise supprimée',
  206.                     'eid'         => $eid,
  207.                     'dateDebut'   => $row['dateDebut'] instanceof \DateTimeInterface $row['dateDebut']->format('d/m/Y') : '',
  208.                     'dateFin'     => $row['dateFin']   instanceof \DateTimeInterface $row['dateFin']->format('d/m/Y')   : '',
  209.                     'fournisseur' => $row['fournisseur'] ?? '',
  210.                     'viewUrl'     => $eid $this->generateUrl('app_entreprise_details', ['id' => $eid]) : null,
  211.                     'editUrl'     => ($eid && $cid) ? $this->generateUrl('app_entreprise_edit_contrat', ['entrepriseId' => $eid'id' => $cid]) : null,
  212.                     'deleteUrl'   => ($eid && $cid) ? $this->generateUrl('app_entreprise_delete_contrat', ['entrepriseId' => $eid'id' => $cid]) : null,
  213.                 ];
  214.             }
  215.         }
  216.         // ---- INTERVALLES DE CONTRATS PAR ENTREPRISE (INDEX DE MOIS)
  217.         $ORIGIN = new \DateTime('2020-01-01 00:00:00');
  218.         $END    = new \DateTime('2040-12-31 00:00:00');
  219.         $companyMonthIntervals = []; // [eid => [[mStart, mEnd], ...] inclusifs]
  220.         $monthIndex = function (\DateTimeInterface $d): int {
  221.             $y = (int) $d->format('Y');
  222.             $m = (int) $d->format('n'); // 1..12
  223.             return ($y 2020) * 12 + ($m 1);
  224.         };
  225.         foreach ($contrats as $contrat) {
  226.             $ent $contrat->getEntreprise();
  227.             if (!$ent) {
  228.                 continue;
  229.             }
  230.             $start $contrat->getDateDebut();
  231.             $end   $contrat->getDateFin();
  232.             if (!$start) {
  233.                 continue;
  234.             }
  235.             $start = (clone $start)->setTime(000);
  236.             // Gaz : +1 jour sur la date de début
  237.             $pdl $contrat->getPdl();
  238.             if ($pdl && isset($isGaz[$pdl])) {
  239.                 $start->modify('+1 day');
  240.             }
  241.             // Fin ouverte => borne
  242.             $end $end ? (clone $end)->setTime(000) : clone $END;
  243.             if ($end $ORIGIN || $start $END) {
  244.                 continue;
  245.             }
  246.             if ($start $ORIGIN) {
  247.                 $start = clone $ORIGIN;
  248.             }
  249.             if ($end $END) {
  250.                 $end = clone $END;
  251.             }
  252.             $mA $monthIndex($start);
  253.             $mB $monthIndex($end);
  254.             if ($mA $mB) {
  255.                 continue;
  256.             }
  257.             $eid $ent->getId();
  258.             $companyMonthIntervals[$eid][] = [$mA$mB];
  259.         }
  260.         // Fusion des intervalles contigus par entreprise
  261.         foreach ($companyMonthIntervals as $eid => $list) {
  262.             if (!$list) {
  263.                 continue;
  264.             }
  265.             usort($list, fn ($x$y) => $x[0] <=> $y[0]);
  266.             $merged = [];
  267.             [$a$b] = $list[0];
  268.             foreach ($list as [$x$y]) {
  269.                 if ($x <= $b 1) {
  270.                     if ($y $b) {
  271.                         $b $y;
  272.                     }
  273.                 } else {
  274.                     $merged[] = [$a$b];
  275.                     [$a$b] = [$x$y];
  276.                 }
  277.             }
  278.             $merged[] = [$a$b];
  279.             $companyMonthIntervals[$eid] = $merged;
  280.         }
  281.         // Infos axe fixe
  282.         $originYear 2020;
  283.         $originMonth 1;
  284.         $endYear 2040;
  285.         $endMonth 12;
  286.         $totalMonths = ($endYear $originYear) * 12 + ($endMonth $originMonth 1);
  287.         $currentQuery $request->query->all();
  288.         return $this->render('entreprise/index.html.twig', [
  289.             'entreprises'            => $array_entreprises,
  290.             'contracts_by_pdl'       => $contractsByPdl,
  291.             'StatutFilter'           => $StatutFilter,
  292.                 'ContratFilter'          => $ContratFilter,
  293.             'currentQuery'           => $currentQuery,
  294.             'origin_year'            => $originYear,
  295.             'origin_month'           => $originMonth,
  296.             'total_months'           => $totalMonths,
  297.             'merged_month_intervals' => $companyMonthIntervals,
  298.         ]);
  299.     }
  300.     /**
  301.      * @Route("/entreprise/contrats-data", name="app_entreprise_contrats_data", methods={"GET"})
  302.      */
  303.     public function contratsData(ManagerRegistry $doctrine): JsonResponse
  304.     {
  305.         $em $doctrine->getManager();
  306.         /** @var Contrat[] $contrats */
  307.         $contrats $em->getRepository(Contrat::class)->findAll();
  308.         // Détection type via listes PDL elec/gaz
  309.         $electricPDLs array_column(
  310.             $em->createQueryBuilder()->select('em.PDL AS p')->from(ElectricMeter::class, 'em')->getQuery()->getScalarResult(),
  311.             'p'
  312.         );
  313.         $gasPDLs array_column(
  314.             $em->createQueryBuilder()->select('gm.PDL AS p')->from(GasMeter::class, 'gm')->getQuery()->getScalarResult(),
  315.             'p'
  316.         );
  317.         $isElec array_fill_keys($electricPDLstrue);
  318.         $isGaz  array_fill_keys($gasPDLstrue);
  319.         // Map Raison Sociale
  320.         $allRs $em->createQueryBuilder()
  321.             ->select('e.id AS id, e.RaisonSociale AS rs')
  322.             ->from(Entreprise::class, 'e')
  323.             ->getQuery()->getArrayResult();
  324.         $rsByIdAll = [];
  325.         foreach ($allRs as $row) {
  326.             $rsByIdAll[(int) $row['id']] = $row['rs'];
  327.         }
  328.         $array_contrats = [];
  329.         foreach ($contrats as $contrat) {
  330.             $ent $contrat->getEntreprise();
  331.             $RaisonSociale $ent ? ($rsByIdAll[$ent->getId()] ?? 'entreprise supprimée') : 'entreprise supprimée';
  332.             $pdl $contrat->getPdl();
  333.             $profil '';
  334.             $fournisseur $contrat->getFournisseur() ?? '';
  335.             // Pastille état (échéance)
  336.             $dateFin $contrat->getDateFin();
  337.             if (!$dateFin) {
  338.                 $etat '<span class="etat-dot etat-blue"></span>';
  339.             } else {
  340.                 $daysRemaining = (int) ((new \DateTime())->diff($dateFin))->format('%r%a');
  341.                 $class $daysRemaining 180 'etat-green' : ($daysRemaining 90 'etat-orange' 'etat-red');
  342.                 $etat '<span class="etat-dot ' $class '"></span>';
  343.             }
  344.             // Type via PDL
  345.             $type $pdl ? (isset($isElec[$pdl]) ? 'elec' : (isset($isGaz[$pdl]) ? 'gaz' '')) : '';
  346.             $actionButtons = ($ent)
  347.                 ? '<div class="d-flex justify-content-center gap-2">
  348.                     <a href="' $this->generateUrl('app_entreprise_edit_contrat', [
  349.                         'entrepriseId' => $ent->getId(),
  350.                         'id' => $contrat->getId()
  351.                     ]) . '" class="btn btn-sm btn-warning" title="Modifier"><i class="fa-solid fa-screwdriver-wrench"></i></a>
  352.                     <a href="' $this->generateUrl('app_entreprise_delete_contrat', [
  353.                         'entrepriseId' => $ent->getId(),
  354.                         'id' => $contrat->getId()
  355.                     ]) . '" class="btn btn-sm btn-danger" title="Supprimer"><i class="fa-solid fa-trash"></i></a>
  356.                 </div>'
  357.                 '';
  358.             $array_contrats[] = [
  359.                 $RaisonSociale,
  360.                 $contrat->getDateDebut() ? $contrat->getDateDebut()->format('d/m/Y') : null,
  361.                 $contrat->getDateFin()   ? $contrat->getDateFin()->format('d/m/Y')   : null,
  362.                 $profil,
  363.                 $fournisseur,
  364.                 $etat,
  365.                 $actionButtons,
  366.                 $type
  367.             ];
  368.         }
  369.         return new JsonResponse([
  370.             'data' => $array_contrats,
  371.         ]);
  372.     }
  373.     /**
  374.      * @Route("/entreprise/pdls-elec-data", name="app_entreprise_pdls_elec_data", methods={"GET"})
  375.      */
  376.     public function pdlsElecData(ManagerRegistry $doctrine): JsonResponse
  377.     {
  378.         $em $doctrine->getManager();
  379.         // Map RS
  380.         $allRs $em->createQueryBuilder()
  381.             ->select('e.id AS id, e.RaisonSociale AS rs')
  382.             ->from(Entreprise::class, 'e')
  383.             ->getQuery()->getArrayResult();
  384.         $rsByIdAll = [];
  385.         foreach ($allRs as $row) {
  386.             $rsByIdAll[(int) $row['id']] = $row['rs'];
  387.         }
  388.         $elecFull $em->createQueryBuilder()
  389.             ->select('
  390.                 em.id,
  391.                 em.entreprise_id AS eid,
  392.                 em.adresse_compteur AS adresseCompteur,
  393.                 em.PDL,
  394.                 em.date_debut AS dateDebut,
  395.                 em.date_fin AS dateFin,
  396.                 em.Profil AS profil,
  397.                 em.CAR,
  398.                 em.fournisseur,
  399.                 em.prix
  400.             ')
  401.             ->from(ElectricMeter::class, 'em')
  402.             ->getQuery()->getArrayResult();
  403.         $pdls_elec = [];
  404.         foreach ($elecFull as $m) {
  405.             $eid = (int) $m['eid'];
  406.             $etat '<span class="etat-dot etat-blue"></span>';
  407.             $actionButtons =
  408.                 '<div class="d-flex justify-content-center gap-2">
  409.                     <a href="' $this->generateUrl('app_electric_meter_edit', ['id' => $m['id']]) . '" class="btn btn-sm btn-warning" title="Modifier"><i class="fa-solid fa-screwdriver-wrench"></i></a>
  410.                     <a href="' $this->generateUrl('app_electric_meter_suppr', ['id' => $m['id']]) . '" class="btn btn-sm btn-danger" title="Supprimer"><i class="fa-solid fa-trash"></i></a>
  411.                 </div>';
  412.             $pdls_elec[] = [
  413.                 $rsByIdAll[$eid] ?? '',
  414.                 $m['adresseCompteur'],
  415.                 $m['PDL'],
  416.                 $m['dateDebut'] instanceof \DateTimeInterface $m['dateDebut']->format('d/m/Y') : '',
  417.                 $m['dateFin']   instanceof \DateTimeInterface $m['dateFin']->format('d/m/Y')   : '',
  418.                 $etat,
  419.                 $m['profil'],
  420.                 $m['CAR'],
  421.                 $m['fournisseur'] ?? '',
  422.                 $m['prix'],
  423.                 $actionButtons,
  424.             ];
  425.         }
  426.         return new JsonResponse([
  427.             'data' => $pdls_elec,
  428.         ]);
  429.     }
  430.     /**
  431.      * @Route("/entreprise/pdls-gaz-data", name="app_entreprise_pdls_gaz_data", methods={"GET"})
  432.      */
  433.     public function pdlsGazData(ManagerRegistry $doctrine): JsonResponse
  434.     {
  435.         $em $doctrine->getManager();
  436.         $allRs $em->createQueryBuilder()
  437.             ->select('e.id AS id, e.RaisonSociale AS rs')
  438.             ->from(Entreprise::class, 'e')
  439.             ->getQuery()->getArrayResult();
  440.         $rsByIdAll = [];
  441.         foreach ($allRs as $row) {
  442.             $rsByIdAll[(int) $row['id']] = $row['rs'];
  443.         }
  444.         $gazFull $em->createQueryBuilder()
  445.             ->select('
  446.                 gm.id,
  447.                 gm.entreprise_id AS eid,
  448.                 gm.adresse_compteur AS adresseCompteur,
  449.                 gm.PDL,
  450.                 gm.date_debut AS dateDebut,
  451.                 gm.date_fin   AS dateFin,
  452.                 gm.profil     AS profil,
  453.                 gm.CAR,
  454.                 gm.fournisseur,
  455.                 gm.prix
  456.             ')
  457.             ->from(GasMeter::class, 'gm')
  458.             ->getQuery()->getArrayResult();
  459.         $pdls_gaz = [];
  460.         foreach ($gazFull as $m) {
  461.             $eid = (int) $m['eid'];
  462.             $etat '<span class="etat-dot etat-blue"></span>';
  463.             $actionButtons =
  464.                 '<div class="d-flex justify-content-center gap-2">
  465.                     <a href="' $this->generateUrl('app_gas_meter_edit', ['id' => $m['id']]) . '" class="btn btn-sm btn-warning" title="Modifier"><i class="fa-solid fa-screwdriver-wrench"></i></a>
  466.                     <a href="' $this->generateUrl('app_gas_meter_suppr', ['id' => $m['id']]) . '" class="btn btn-sm btn-danger" title="Supprimer"><i class="fa-solid fa-trash"></i></a>
  467.                 </div>';
  468.             $pdls_gaz[] = [
  469.                 $rsByIdAll[$eid] ?? '',
  470.                 $m['adresseCompteur'],
  471.                 $m['PDL'],
  472.                 $m['dateDebut'] instanceof \DateTimeInterface $m['dateDebut']->format('d/m/Y') : '',
  473.                 $m['dateFin']   instanceof \DateTimeInterface $m['dateFin']->format('d/m/Y')   : '',
  474.                 $etat,
  475.                 $m['profil'],
  476.                 $m['CAR'],
  477.                 $m['fournisseur'] ?? '',
  478.                 $m['prix'],
  479.                 $actionButtons,
  480.             ];
  481.         }
  482.         return new JsonResponse([
  483.             'data' => $pdls_gaz,
  484.         ]);
  485.     }
  486.     /**
  487.      * @Route("/entreprise/calculate-value", name="app_entreprise_calculate_value", methods={"POST"})
  488.      */
  489.     public function calculateValue(Request $requestManagerRegistry $doctrine): JsonResponse
  490.     {
  491.         $this->logger->debug('Received calculate value request', [
  492.             'car' => $request->request->get('car'),
  493.             'dateDebut' => $request->request->get('dateDebut'),
  494.             'dateFin' => $request->request->get('dateFin'),
  495.             'pdl' => $request->request->get('pdl'),
  496.             'raw_request' => $request->request->all()
  497.         ]);
  498.         // Validate CSRF token
  499.         $submittedToken $request->headers->get('X-CSRF-Token');
  500.         if (!$this->isCsrfTokenValid('calculate-value'$submittedToken)) {
  501.             $this->logger->error('Invalid CSRF token');
  502.             return new JsonResponse(['error' => 'Invalid CSRF token'], 403);
  503.         }
  504.         try {
  505.             $car floatval($request->request->get('car'));
  506.             if ($car <= 0) {
  507.                 throw new \InvalidArgumentException('CAR must be greater than 0');
  508.             }
  509.             $dateDebut = new \DateTime($request->request->get('dateDebut'));
  510.             $dateDebut->setTime(000);
  511.             $dateFin = new \DateTime($request->request->get('dateFin'));
  512.             $dateFin->setTime(000);
  513.             if ($dateDebut $dateFin) {
  514.                 throw new \InvalidArgumentException('Start date must be before end date');
  515.             }
  516.             $pdl $request->request->get('pdl');
  517.             $isGasContract false;
  518.             if ($pdl) {
  519.                 $gasMeter $doctrine->getRepository(GasMeter::class)->findOneBy(['PDL' => $pdl]);
  520.                 if ($gasMeter) {
  521.                     $isGasContract true;
  522.                     $dateDebut->modify('+1 day');
  523.                 }
  524.             }
  525.             $contrat = new Contrat();
  526.             $contrat->setCar($car);
  527.             $contrat->setDateDebut($dateDebut);
  528.             $contrat->setDateFin($dateFin);
  529.             if ($pdl) {
  530.                 $contrat->setPdl($pdl);
  531.             }
  532.             $value $this->pricingService->calculateAnnualValue($contrat);
  533.             $this->logger->debug('Calculated contract value', [
  534.                 'car' => $car,
  535.                 'dateDebut' => $dateDebut->format('d/m/Y'),
  536.                 'dateFin' => $dateFin->format('d/m/Y'),
  537.                 'isGasContract' => $isGasContract,
  538.                 'value' => $value
  539.             ]);
  540.             return new JsonResponse([
  541.                 'value' => $value,
  542.                 'debug' => [
  543.                     'car' => $car,
  544.                     'dateDebut' => $dateDebut->format('d/m/Y'),
  545.                     'dateFin' => $dateFin->format('d/m/Y'),
  546.                     'isGasContract' => $isGasContract
  547.                 ]
  548.             ]);
  549.         } catch (\Exception $e) {
  550.             $this->logger->error('Error calculating contract value', [
  551.                 'error' => $e->getMessage(),
  552.                 'trace' => $e->getTraceAsString()
  553.             ]);
  554.             return new JsonResponse(['error' => 'Error calculating value: ' $e->getMessage()], 500);
  555.         }
  556.     }
  557.     /**
  558.      * @Route("/entreprise/add", name="app_entreprise_add")
  559.      */
  560.     public function add(Request $requestEntityManagerInterface $entityManager): Response
  561.     {
  562.         $entreprises = new Entreprise();
  563.         $utilisateurs $entityManager->createQueryBuilder()
  564.             ->select('u')
  565.             ->from(User::class, 'u')
  566.             ->where('u.roles LIKE :roles')
  567.             ->setParameter('roles''%ROLE_TEAM%')
  568.             ->getQuery()
  569.             ->getResult();
  570.         $array_utilisateurs = [];
  571.         for ($i 0$i count($utilisateurs); $i++) {
  572.             $array_utilisateurs[$utilisateurs[$i]->getUsername()] = $utilisateurs[$i]->getId();
  573.         }
  574.         $form $this->createForm(EntrepriseType::class, $entreprises, ['utilisateurs' => $array_utilisateurs]);
  575.         $form->handleRequest($request);
  576.         if ($form->isSubmitted() && $form->isValid()) {
  577.             $entityManager->persist($entreprises);
  578.             $entityManager->flush();
  579.             return $this->redirectToRoute('app_entreprise');
  580.         }
  581.         return $this->render('entreprise/add.html.twig', [
  582.             'entrepriseForm' => $form->createView(),
  583.             'array_utilisateurs' => $array_utilisateurs,
  584.         ]);
  585.     }
  586.     /**
  587.      * @Route("/entreprise/edit/{id}", name="app_entreprise_edit")
  588.      */
  589.     public function edit(int $idRequest $requestEntityManagerInterface $entityManagerManagerRegistry $doctrine): Response
  590.     {
  591.         $entreprise $doctrine->getRepository(Entreprise::class)->findOneBy(['id' => $id]);
  592.         $utilisateurs $entityManager->createQueryBuilder()
  593.             ->select('u')
  594.             ->from(User::class, 'u')
  595.             ->where('u.roles LIKE :roles')
  596.             ->setParameter('roles''%ROLE_TEAM%')
  597.             ->getQuery()
  598.             ->getResult();
  599.         $array_utilisateurs = [];
  600.         for ($i 0$i count($utilisateurs); $i++) {
  601.             $array_utilisateurs[$utilisateurs[$i]->getUsername()] = $utilisateurs[$i]->getId();
  602.         }
  603.         $form $this->createForm(EntrepriseType::class, $entreprise, ['utilisateurs' => $array_utilisateurs]);
  604.         $form->handleRequest($request);
  605.         $entreprise_entity = [
  606.             'raison_sociale' => $entreprise->getRaisonSociale(),
  607.             'siret' => $entreprise->getSiret(),
  608.             'naf' => $entreprise->getNaf(),
  609.             'rcs' => $entreprise->getRcs(),
  610.             'num_voie' => $entreprise->getNumVoie(),
  611.             'adresse' => $entreprise->getAdresse(),
  612.             'code_postal' => $entreprise->getCodePostal(),
  613.             'commune' => $entreprise->getCommune(),
  614.             'code_insee' => $entreprise->getCodeInsee(),
  615.             'Statut' => $entreprise->getStatut(),
  616.             'utilisateur' => $entreprise->getUtilisateur(),
  617.         ];
  618.         if ($form->isSubmitted() && $form->isValid()) {
  619.             $entreprisesEdit $form->getData();
  620.             if ($entreprisesEdit->getRaisonSociale() != null) {
  621.                 $entreprise->setRaisonSociale($entreprisesEdit->getRaisonSociale());
  622.             }
  623.             if ($entreprisesEdit->getSiret() != null) {
  624.                 $entreprise->setSiret($entreprisesEdit->getSiret());
  625.             }
  626.             if ($entreprisesEdit->getNaf() != null) {
  627.                 $entreprise->setNaf($entreprisesEdit->getNaf());
  628.             }
  629.             if ($entreprisesEdit->getRcs() != null) {
  630.                 $entreprise->setRcs($entreprisesEdit->getRcs());
  631.             }
  632.             if ($entreprisesEdit->getNumVoie() != null) {
  633.                 $entreprise->setNumVoie($entreprisesEdit->getNumVoie());
  634.             }
  635.             if ($entreprisesEdit->getAdresse() != null) {
  636.                 $entreprise->setAdresse($entreprisesEdit->getAdresse());
  637.             }
  638.             if ($entreprisesEdit->getCodePostal() != null) {
  639.                 $entreprise->setCodePostal($entreprisesEdit->getCodePostal());
  640.             }
  641.             if ($entreprisesEdit->getCommune() != null) {
  642.                 $entreprise->setCommune($entreprisesEdit->getCommune());
  643.             }
  644.             if ($entreprisesEdit->getCodeInsee() != null) {
  645.                 $entreprise->setCodeInsee($entreprisesEdit->getCodeInsee());
  646.             }
  647.             if ($entreprisesEdit->getStatut() != null) {
  648.                 $entreprise->setStatut($entreprisesEdit->getStatut());
  649.             }
  650.             if ($entreprisesEdit->getUtilisateur() != null) {
  651.                 $entreprise->setUtilisateur(array_map('strval'$entreprisesEdit->getUtilisateur()));
  652.             }
  653.             $entityManager->persist($entreprise);
  654.             $entityManager->flush();
  655.             return $this->redirectToRoute('app_entreprise');
  656.         }
  657.         return $this->render('entreprise/edit.html.twig', [
  658.             'entrepriseForm' => $form->createView(),
  659.             'entreprise' => $entreprise_entity
  660.         ]);
  661.     }
  662.     /**
  663.      * @Route("/entreprise/suppr/{id}", name="app_entreprise_suppr")
  664.      */
  665.     public function suppr(int $idRequest $requestEntityManagerInterface $entityManagerManagerRegistry $doctrine): Response
  666.     {
  667.         $notes $doctrine->getRepository(Note::class)->findBy(['entreprise_id' => $id]);
  668.         foreach ($notes as $note) {
  669.             $entityManager->remove($note);
  670.             $entityManager->flush();
  671.         }
  672.         $rappels $doctrine->getRepository(Rappel::class)->findBy(['entreprise_id' => $id]);
  673.         foreach ($rappels as $rappel) {
  674.             $entityManager->remove($rappel);
  675.             $entityManager->flush();
  676.         }
  677.         $electric_meters $doctrine->getRepository(ElectricMeter::class)->findBy(['entreprise_id' => $id]);
  678.         foreach ($electric_meters as $em) {
  679.             $entityManager->remove($em);
  680.             $entityManager->flush();
  681.         }
  682.         $gas_meters $doctrine->getRepository(GasMeter::class)->findBy(['entreprise_id' => $id]);
  683.         foreach ($gas_meters as $gm) {
  684.             $entityManager->remove($gm);
  685.             $entityManager->flush();
  686.         }
  687.         $cspes $doctrine->getRepository(CSPE::class)->findBy(['entreprise_id' => $id]);
  688.         foreach ($cspes as $cspe) {
  689.             $entityManager->remove($cspe);
  690.             $entityManager->flush();
  691.         }
  692.         $espace_clients $doctrine->getRepository(EspaceClient::class)->findBy(['entreprise_id' => $id]);
  693.         foreach ($espace_clients as $ec) {
  694.             $entityManager->remove($ec);
  695.             $entityManager->flush();
  696.         }
  697.         $contacts $doctrine->getRepository(Contact::class)->findBy(['entreprise_id' => $id]);
  698.         foreach ($contacts as $contact) {
  699.             $entityManager->remove($contact);
  700.             $entityManager->flush();
  701.         }
  702.         $entreprise $doctrine->getRepository(Entreprise::class)->findOneBy(['id' => $id]);
  703.         if ($entreprise) {
  704.             $entityManager->remove($entreprise);
  705.             $entityManager->flush();
  706.         }
  707.         return $this->redirectToRoute('app_entreprise');
  708.     }
  709.     /**
  710.      * @Route("/entreprise/details/{id}", name="app_entreprise_details")
  711.      */
  712.     public function details(int $idManagerRegistry $doctrine): Response
  713.     {
  714.         $entreprise $doctrine->getRepository(Entreprise::class)->findOneBy(['id' => $id]);
  715.         if (!$entreprise) {
  716.             return $this->redirectToRoute('app_requetes');
  717.         }
  718.         $userIds $entreprise->getUtilisateur();
  719.         $user_names = [];
  720.         if (!empty($userIds)) {
  721.             foreach ($userIds as $userId) {
  722.                 $user $doctrine->getRepository(User::class)->find((int) $userId);
  723.                 if ($user) {
  724.                     $user_names[] = $user->getUsername();
  725.                 }
  726.             }
  727.         }
  728.         $entreprise_entity = [
  729.             'id' => $entreprise->getId(),
  730.             'raison_sociale' => $entreprise->getRaisonSociale(),
  731.             'siret' => $entreprise->getSiret(),
  732.             'naf' => $entreprise->getNaf(),
  733.             'rcs' => $entreprise->getRcs(),
  734.             'num_voie' => $entreprise->getNumVoie(),
  735.             'adresse' => $entreprise->getAdresse(),
  736.             'code_postal' => $entreprise->getCodePostal(),
  737.             'commune' => $entreprise->getCommune(),
  738.             'code_insee' => $entreprise->getCodeInsee(),
  739.             'Statut' => $entreprise->getStatut(),
  740.             'utilisateur' => $user_names,
  741.         ];
  742.         $notes $doctrine->getRepository(Note::class)->findBy(['entreprise_id' => $id], ['date_creation' => 'DESC']);
  743.         $array_notes = [];
  744.         foreach ($notes as $note) {
  745.             $user $note->getUser();
  746.             $array_notes[] = [
  747.                 'date_creation' => $note->getDateCreation() ? $note->getDateCreation()->format('d/m/Y') : '',
  748.                 'texte' => $note->getTexte(),
  749.                 'user' => $user $user->getUsername() : 'Non défini',
  750.                 'edit_url' => $this->generateUrl('app_note_edit', ['id' => $note->getId()]),
  751.                 'delete_url' => $this->generateUrl('app_note_suppr', ['id' => $note->getId()]),
  752.             ];
  753.         }
  754.         $rappels $doctrine->getRepository(Rappel::class)->findBy(['entreprise_id' => $id]);
  755.         $array_rappels = [];
  756.         foreach ($rappels as $rappel) {
  757.             $array_rappels[] = [
  758.                 $rappel->getTitre(),
  759.                 $rappel->getDescription(),
  760.                 $rappel->getEcheance()->format('d/m/Y'),
  761.                 $rappel->isCompleter(),
  762.                 '<a href="' $this->generateUrl('app_rappel_edit', ['id' => $rappel->getId()]) . '" type="button" class="btn btn-sm btn-primary mb-1">Modifier</a>
  763.                 <a href="' $this->generateUrl('app_rappel_suppr', ['id' => $rappel->getId()]) . '" type="button" class="btn btn-sm btn-danger ">Supprimer</a>',
  764.             ];
  765.         }
  766.         $electric_meters $doctrine->getRepository(ElectricMeter::class)->findBy(['entreprise_id' => $id]);
  767.         $array_electric_meters array_map(function ($meter) {
  768.             return [
  769.                 'pdl' => $meter->getPDL(),
  770.                 'id' => $meter->getId(),
  771.             ];
  772.         }, $electric_meters);
  773.         $electric_pdls array_map(function ($meter) {
  774.             return $meter->getPDL();
  775.         }, $electric_meters);
  776.         $gas_meters $doctrine->getRepository(GasMeter::class)->findBy(['entreprise_id' => $id]);
  777.         $array_gas_meters array_map(function ($meter) {
  778.             return [
  779.                 'pdl' => $meter->getPDL(),
  780.                 'id' => $meter->getId(),
  781.             ];
  782.         }, $gas_meters);
  783.         $gas_pdls array_map(function ($meter) {
  784.             return $meter->getPDL();
  785.         }, $gas_meters);
  786.         $cspes $doctrine->getRepository(CSPE::class)->findBy(['entreprise_id' => $id]);
  787.         $array_cspes = [];
  788.         for ($i 0$i count($cspes); $i++) {
  789.             $array_cspes[$i] = [
  790.                 $cspes[$i]->getNotes(),
  791.                 date_format($cspes[$i]->getDate(), 'd/m/Y'),
  792.                 $cspes[$i]->getValeur(),
  793.                 '<a href="' $this->generateUrl('app_cspe_edit', ['id' => $cspes[$i]->getId()]) . '" type="button" class="btn btn-sm btn-warning mb-1">Modifier</a>
  794.                 <a href="' $this->generateUrl('app_cspe_suppr', ['id' => $cspes[$i]->getId()]) . '" type="button" class="btn btn-sm btn-danger ">Supprimer</a>',
  795.             ];
  796.         }
  797.         $espace_clients $doctrine->getRepository(EspaceClient::class)->findBy(['entreprise_id' => $id]);
  798.         $array_espace_clients = [];
  799.         for ($i 0$i count($espace_clients); $i++) {
  800.             $lien $espace_clients[$i]->getLien();
  801.             if (!preg_match("~^(?:f|ht)tps?://~i"$lien)) {
  802.                 $lien "http://" $lien;
  803.             }
  804.             $domain parse_url($lienPHP_URL_HOST) ?: $lien;
  805.             $domainParts explode('.'$domain);
  806.             $buttonText count($domainParts) > $domainParts[1] : $domain;
  807.             $array_espace_clients[$i] = [
  808.                 $espace_clients[$i]->getFournisseur(),
  809.                 $espace_clients[$i]->getLogin(),
  810.                 $espace_clients[$i]->getMdp(),
  811.                 '<a href="' $lien '" target="_blank" type="button" class="btn btn-primary">' $buttonText '</a>',
  812.                 '<a href="' $this->generateUrl('app_espace_client_edit', ['id' => $espace_clients[$i]->getId()]) . '" type="button" class="btn btn-sm btn-warning mb-1">Modifier</a>
  813.                 <a href="' $this->generateUrl('app_espace_client_suppr', ['id' => $espace_clients[$i]->getId()]) . '" type="button" class="btn btn-sm btn-danger ">Supprimer</a>',
  814.             ];
  815.         }
  816.         $contacts $doctrine->getRepository(Contact::class)->findBy(['entreprise_id' => $id]);
  817.         $array_contacts = [];
  818.         for ($i 0$i count($contacts); $i++) {
  819.             $array_contacts[$i] = [
  820.                 $contacts[$i]->getNom(),
  821.                 $contacts[$i]->getPrenom(),
  822.                 $contacts[$i]->getCivilite(),
  823.                 $contacts[$i]->getFonction(),
  824.                 $contacts[$i]->getFixe(),
  825.                 $contacts[$i]->getEmail(),
  826.                 $contacts[$i]->getPortable(),
  827.                     '<div class="contact-actions">
  828.                         <a href="' $this->generateUrl('app_contact_edit', ['id' => $contacts[$i]->getId()]) . '" class="btn btn-sm btn-warning" title="Modifier" aria-label="Modifier">
  829.                             <i class="fa-solid fa-pen"></i>
  830.                         </a>
  831.                         <a href="' $this->generateUrl('app_contact_suppr', ['id' => $contacts[$i]->getId()]) . '" class="btn btn-sm btn-danger" title="Supprimer" aria-label="Supprimer">
  832.                             <i class="fa-solid fa-trash"></i>
  833.                         </a>
  834.                     </div>',
  835.             ];
  836.         }
  837.         $contrats $doctrine->getRepository(Contrat::class)->findBy(['entreprise' => $entreprise]);
  838.         $array_contrats = [];
  839.         foreach ($contrats as $contrat) {
  840.             $array_contrats[] = [
  841.                 "id" => $contrat->getId(),
  842.                 "duree" => $contrat->getDuree(),
  843.                 "valeur" => $contrat->getValeur(),
  844.                 "pdl" => $contrat->getPdl(),
  845.                 "car" => $contrat->getCar(),
  846.                 "prix_moyen" => $contrat->getPrixMoyen(),
  847.                 "fournisseur" => $contrat->getFournisseur(),
  848.                 "date_debut" => $contrat->getDateDebut() ? $contrat->getDateDebut()->format('d/m/Y') : '',
  849.                 "date_fin" => $contrat->getDateFin() ? $contrat->getDateFin()->format('d/m/Y') : '',
  850.                 "date_signature" => $contrat->getDateSignature() ? $contrat->getDateSignature()->format('d/m/Y') : '',
  851.                 '<a href="' $this->generateUrl('app_entreprise_edit_contrat', ['entrepriseId' => $entreprise->getId(), 'id' => $contrat->getId()]) . '" type="button" class="btn btn-sm btn-warning mb-1">Modifier</a>
  852.                 <a href="' $this->generateUrl('app_entreprise_delete_contrat', ['entrepriseId' => $entreprise->getId(), 'id' => $contrat->getId()]) . '" type="button" class="btn btn-sm btn-danger">Supprimer</a>',
  853.             ];
  854.         }
  855.         return $this->render('entreprise/details.html.twig', [
  856.             'entreprise' => $entreprise_entity,
  857.             'notes' => $array_notes,
  858.             'rappels' => $array_rappels,
  859.             'electric_meters' => $array_electric_meters,
  860.             'gas_meters' => $array_gas_meters,
  861.             'electric_pdls' => $electric_pdls,
  862.             'gas_pdls' => $gas_pdls,
  863.             'cspes' => $array_cspes,
  864.             'espace_clients' => $array_espace_clients,
  865.             'contacts' => $array_contacts,
  866.             'contrats' => $array_contrats,
  867.         ]);
  868.     }
  869.     /**
  870.      * @Route("/entreprise/electric_meter/details/{id}", name="app_electric_meter_details")
  871.      */
  872.     public function electricMeterDetails(Request $requestint $idManagerRegistry $doctrine): JsonResponse
  873.     {
  874.         $pdl $request->query->get('pdl');
  875.         if (!$pdl) {
  876.             return new JsonResponse(['error' => 'PDL parameter is required'], 400);
  877.         }
  878.         $entreprise $doctrine->getRepository(Entreprise::class)->find($id);
  879.         if (!$entreprise) {
  880.             return new JsonResponse(['error' => 'Entreprise not found'], 404);
  881.         }
  882.         $electricMeter $doctrine->getRepository(ElectricMeter::class)->findOneBy([
  883.             'entreprise_id' => $id,
  884.             'PDL' => $pdl
  885.         ]);
  886.         if (!$electricMeter) {
  887.             return new JsonResponse(['error' => 'Electric meter not found'], 404);
  888.         }
  889.         $meterDetails = [
  890.             'adresseCompteur' => $electricMeter->getAdresseCompteur(),
  891.             'PDL' => $electricMeter->getPDL(),
  892.             'dateDebut' => $electricMeter->getDateDebut() ? $electricMeter->getDateDebut()->format('d/m/Y') : '',
  893.             'dateFin' => $electricMeter->getDateFin() ? $electricMeter->getDateFin()->format('d/m/Y') : '',
  894.             'PS' => $electricMeter->getPS(),
  895.             'profil' => $electricMeter->getProfil(),
  896.             'CAR' => $electricMeter->getCAR(),
  897.             'fournisseur' => $electricMeter->getFournisseur(),
  898.             'prix' => $electricMeter->getPrix()
  899.         ];
  900.         return new JsonResponse($meterDetails);
  901.     }
  902.     /**
  903.      * @Route("/entreprise/{id}/gas-meter-details", name="app_gas_meter_details")
  904.      */
  905.     public function gasMeterDetails(Request $requestint $idManagerRegistry $doctrine): JsonResponse
  906.     {
  907.         $pdl $request->query->get('pdl');
  908.         if (!$pdl) {
  909.             return new JsonResponse(['error' => 'PDL parameter is required'], 400);
  910.         }
  911.         $entreprise $doctrine->getRepository(Entreprise::class)->find($id);
  912.         if (!$entreprise) {
  913.             return new JsonResponse(['error' => 'Entreprise not found'], 404);
  914.         }
  915.         $gasMeter $doctrine->getRepository(GasMeter::class)->findOneBy([
  916.             'entreprise_id' => $id,
  917.             'PDL' => $pdl
  918.         ]);
  919.         if (!$gasMeter) {
  920.             return new JsonResponse(['error' => 'Gas meter not found'], 404);
  921.         }
  922.         $meterDetails = [
  923.             'adresseCompteur' => $gasMeter->getAdresseCompteur(),
  924.             'PDL' => $gasMeter->getPDL(),
  925.             'dateDebut' => $gasMeter->getDateDebut() ? $gasMeter->getDateDebut()->format('d/m/Y') : '',
  926.             'dateFin' => $gasMeter->getDateFin() ? $gasMeter->getDateFin()->format('d/m/Y') : '',
  927.             'profil' => $gasMeter->getProfil(),
  928.             'CAR' => $gasMeter->getCAR(),
  929.             'fournisseur' => $gasMeter->getFournisseur(),
  930.             'prix' => $gasMeter->getPrix(),
  931.         ];
  932.         return new JsonResponse($meterDetails);
  933.     }
  934.     /**
  935.      * @Route("/entreprise/infoclient", name="app_entreprise_infoclient")
  936.      */
  937.     public function infoclient(HttpClientInterface $httpClient): JsonResponse
  938.     {
  939.         $url 'https://api.societe.com/api/v1/infoclient';
  940.         $headers = [
  941.             'headers' => [
  942.                 'X-Authorization' => 'socapi 8938e836988619dc20be14360fba30e3',
  943.             ],
  944.         ];
  945.         $response $httpClient->request('GET'$url$headers);
  946.         return new JsonResponse($response->toArray());
  947.     }
  948.     /**
  949.      * @Route("/entreprise/info_entreprise/{numero}", name="app_entreprise_info_entreprise")
  950.      */
  951.     public function info_entreprise(HttpClientInterface $httpClientManagerRegistry $doctrine$numero): JsonResponse
  952.     {
  953.         $entreprise $doctrine->getRepository(Entreprise::class)->findOneBy(['Siret' => $numero]);
  954.         if ($entreprise != null) {
  955.             return new JsonResponse("existant");
  956.         }
  957.         $url 'https://api.societe.com/api/v1/entreprise/' $numero '/infoslegales';
  958.         $headers = [
  959.             'headers' => [
  960.                 'X-Authorization' => 'socapi 8938e836988619dc20be14360fba30e3',
  961.             ],
  962.         ];
  963.         $response $httpClient->request('GET'$url$headers);
  964.         return new JsonResponse($response->toArray());
  965.     }
  966.     /**
  967.      * @Route("/entreprise/{id}/new-contrat", name="app_entreprise_new_contrat")
  968.      */
  969.     public function newContrat(Request $requestEntityManagerInterface $entityManagerManagerRegistry $doctrineint $id): Response
  970.     {
  971.         $entreprise $doctrine->getRepository(Entreprise::class)->find($id);
  972.         if (!$entreprise) {
  973.             throw $this->createNotFoundException('Entreprise not found');
  974.         }
  975.         $contrat = new Contrat();
  976.         $contrat->setEntreprise($entreprise);
  977.         $meterId $request->query->get('meterId');
  978.         $meterType $request->query->get('meterType');
  979.         if ($meterId && $meterType) {
  980.             $meter null;
  981.             if ($meterType === 'electric') {
  982.                 $meter $doctrine->getRepository(ElectricMeter::class)->find($meterId);
  983.             } elseif ($meterType === 'gas') {
  984.                 $meter $doctrine->getRepository(GasMeter::class)->find($meterId);
  985.             }
  986.             if ($meter) {
  987.                 $contrat->setPdl($meter->getPDL());
  988.                 $contrat->setCar($meter->getCAR());
  989.                 $contrat->setPrixMoyen($meter->getPrix());
  990.                 $contrat->setFournisseur($meter->getFournisseur());
  991.                 $contrat->setDateDebut($meter->getDateDebut());
  992.                 $contrat->setDateFin($meter->getDateFin());
  993.                 if ($meter->getDateDebut() && $meter->getDateFin()) {
  994.                     $dateDebut $meter->getDateDebut();
  995.                     if ($dateDebut) {
  996.                         if ($meterType === 'gas') {
  997.                             $dateDebut->modify('+1 day');
  998.                         }
  999.                     }
  1000.                     $duration $this->calculateDurationInMonths($dateDebut$meter->getDateFin());
  1001.                     $contrat->setDuree($duration);
  1002.                     $annualValue $this->pricingService->calculateAnnualValue($contrat);
  1003.                     $contrat->setValeur($annualValue);
  1004.                 }
  1005.             }
  1006.         }
  1007.         $pdlChoices $this->getPDLChoicesForEntreprise($doctrine$entreprise);
  1008.         $form $this->createForm(ContratType::class, $contrat, [
  1009.             'pdl_choices' => $pdlChoices
  1010.         ]);
  1011.         $form->handleRequest($request);
  1012.         if ($form->isSubmitted() && $form->isValid()) {
  1013.             $duration $this->calculateDurationInMonths($contrat->getDateDebut(), $contrat->getDateFin());
  1014.             $contrat->setDuree($duration);
  1015.             $submittedValue $form->get('valeur')->getData();
  1016.             if ($submittedValue === null || $submittedValue === 0.0) {
  1017.                 $annualValue $this->pricingService->calculateAnnualValue($contrat);
  1018.                 $contrat->setValeur($annualValue);
  1019.             }
  1020.             $userIds $entreprise->getUtilisateur();
  1021.             if (!empty($userIds)) {
  1022.                 $user $doctrine->getRepository(User::class)->find((int) $userIds[0]);
  1023.                 if ($user) {
  1024.                     $contrat->setCollaborateur($user);
  1025.                 }
  1026.             }
  1027.             $entityManager->persist($contrat);
  1028.             $entityManager->flush();
  1029.             if ($request->isXmlHttpRequest()) {
  1030.                 return new JsonResponse([
  1031.                     'success' => true,
  1032.                     'contractId' => $contrat->getId(),
  1033.                     'message' => 'Le contrat a été créé avec succès.'
  1034.                 ]);
  1035.             }
  1036.             return $this->redirectToRoute('app_entreprise_details', ['id' => $entreprise->getId()]);
  1037.         }
  1038.         return $this->render('entreprise/new_contrat.html.twig', [
  1039.             'entreprise' => $entreprise,
  1040.             'form' => $form->createView(),
  1041.         ]);
  1042.     }
  1043.     /**
  1044.      * @Route("/entreprise/{entrepriseId}/edit-contrat/{id}", name="app_entreprise_edit_contrat")
  1045.      */
  1046.     public function editContrat(Request $requestEntityManagerInterface $entityManagerManagerRegistry $doctrineint $entrepriseIdint $id): Response
  1047.     {
  1048.         $entreprise $doctrine->getRepository(Entreprise::class)->find($entrepriseId);
  1049.         $contrat $doctrine->getRepository(Contrat::class)->find($id);
  1050.         if (!$entreprise) {
  1051.             throw $this->createNotFoundException('Entreprise not found');
  1052.         }
  1053.         if (!$contrat) {
  1054.             throw $this->createNotFoundException('Contrat not found');
  1055.         }
  1056.         $isGasContract false;
  1057.         $gasMeter $doctrine->getRepository(GasMeter::class)->findOneBy([
  1058.             'entreprise_id' => $entrepriseId,
  1059.             'PDL' => $contrat->getPdl()
  1060.         ]);
  1061.         if ($gasMeter) {
  1062.             $isGasContract true;
  1063.         }
  1064.         $contrat->setEntreprise($entreprise);
  1065.         $pdlChoices $this->getPDLChoicesForEntreprise($doctrine$entreprise);
  1066.         $form $this->createForm(ContratType::class, $contrat, [
  1067.             'pdl_choices' => $pdlChoices
  1068.         ]);
  1069.         $form->handleRequest($request);
  1070.         if ($form->isSubmitted() && $form->isValid()) {
  1071.             $contrat->setEntreprise($entreprise);
  1072.             $dateDebut $contrat->getDateDebut();
  1073.             if ($dateDebut) {
  1074.                 if ($isGasContract) {
  1075.                     $dateDebut->modify('+1 day');
  1076.                 }
  1077.             }
  1078.             $duration $this->calculateDurationInMonths($dateDebut$contrat->getDateFin());
  1079.             $contrat->setDuree($duration);
  1080.             $submittedValue $form->get('valeur')->getData();
  1081.             if ($submittedValue === null || $submittedValue === 0.0) {
  1082.                 $annualValue $this->pricingService->calculateAnnualValue($contrat);
  1083.                 $contrat->setValeur($annualValue);
  1084.             }
  1085.             $entityManager->flush();
  1086.             return $this->redirectToRoute('app_entreprise_details', ['id' => $entreprise->getId()]);
  1087.         }
  1088.         return $this->render('entreprise/edit_contrat.html.twig', [
  1089.             'entreprise' => $entreprise,
  1090.             'contrat' => $contrat,
  1091.             'form' => $form->createView(),
  1092.         ]);
  1093.     }
  1094.     /**
  1095.      * @Route("/entreprise/{entrepriseId}/delete-contrat/{id}", name="app_entreprise_delete_contrat")
  1096.      */
  1097.     public function deleteContrat(Request $requestEntityManagerInterface $entityManagerManagerRegistry $doctrineint $entrepriseIdint $id): Response
  1098.     {
  1099.         $entreprise $doctrine->getRepository(Entreprise::class)->find($entrepriseId);
  1100.         $contrat $doctrine->getRepository(Contrat::class)->find($id);
  1101.         if (!$entreprise) {
  1102.             throw $this->createNotFoundException('Entreprise not found');
  1103.         }
  1104.         if (!$contrat) {
  1105.             throw $this->createNotFoundException('Contrat not found');
  1106.         }
  1107.         if ($this->isCsrfTokenValid('delete' $contrat->getId(), $request->request->get('_token'))) {
  1108.             $entityManager->remove($contrat);
  1109.             $entityManager->flush();
  1110.         }
  1111.         return $this->redirectToRoute('app_entreprise_details', ['id' => $entreprise->getId()]);
  1112.     }
  1113.     private function calculateDurationInMonths(?\DateTimeInterface $dateDebut, ?\DateTimeInterface $dateFin): ?int
  1114.     {
  1115.         if (!$dateDebut || !$dateFin) {
  1116.             return null;
  1117.         }
  1118.         $interval $dateDebut->diff($dateFin);
  1119.         return $interval->12 $interval->m;
  1120.     }
  1121.     private function getPDLChoicesForEntreprise(ManagerRegistry $doctrineEntreprise $entreprise): array
  1122.     {
  1123.         $electricMeters $doctrine->getRepository(ElectricMeter::class)->findBy(['entreprise_id' => $entreprise->getId()]);
  1124.         $gasMeters $doctrine->getRepository(GasMeter::class)->findBy(['entreprise_id' => $entreprise->getId()]);
  1125.         $pdlChoices = [];
  1126.         foreach ($electricMeters as $meter) {
  1127.             $pdlChoices[$meter->getPDL()] = $meter->getPDL();
  1128.         }
  1129.         foreach ($gasMeters as $meter) {
  1130.             $pdlChoices[$meter->getPDL()] = $meter->getPDL();
  1131.         }
  1132.         return $pdlChoices;
  1133.     }
  1134.     /**
  1135.      * @Route("/entreprise/associate-user", name="app_entreprise_associate_user")
  1136.      */
  1137.     public function associateUser(Request $requestEntityManagerInterface $entityManager): Response
  1138.     {
  1139.         $this->denyAccessUnlessGranted('ROLE_COMPTA');
  1140.         try {
  1141.             $form $this->createForm(UserEntrepriseType::class);
  1142.             $form->handleRequest($request);
  1143.             if ($form->isSubmitted() && $form->isValid()) {
  1144.                 $data $form->getData();
  1145.                 /** @var User $user */
  1146.                 $user $data['user'];
  1147.                 $entreprises $data['entreprises'];
  1148.                 if (!$user || !$entreprises || empty($entreprises)) {
  1149.                     throw new \InvalidArgumentException('Utilisateur et entreprises sont requis');
  1150.                 }
  1151.                 if (!$user->hasRole('ROLE_CLIENT_PRO')) {
  1152.                     $roles $user->getRoles();
  1153.                     $roles[] = 'ROLE_CLIENT_PRO';
  1154.                     $user->setRoles(array_unique($roles));
  1155.                 }
  1156.                 foreach ($entreprises as $entreprise) {
  1157.                     if (!$user->getEntreprises()->contains($entreprise)) {
  1158.                         $user->addEntreprise($entreprise);
  1159.                         $entreprise->addUtilisateur(strval($user->getId()));
  1160.                     }
  1161.                 }
  1162.                 $entityManager->persist($user);
  1163.                 $entityManager->flush();
  1164.                 $this->addFlash('success'sprintf(
  1165.                     'L\'utilisateur %s a été associé avec succès à %d entreprise(s)',
  1166.                     $user->getUsername(),
  1167.                     count($entreprises)
  1168.                 ));
  1169.                 return $this->redirectToRoute('app_entreprise');
  1170.             }
  1171.             return $this->render('entreprise/associate_user.html.twig', [
  1172.                 'form' => $form->createView(),
  1173.             ]);
  1174.         } catch (\Exception $e) {
  1175.             $this->addFlash('error''Une erreur est survenue lors de l\'association : ' $e->getMessage());
  1176.             return $this->redirectToRoute('app_entreprise_associate_user');
  1177.         }
  1178.     }
  1179. }