src/Controller/EntrepriseController.php line 218

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