<?php
namespace App\Controller;
use App\Entity\CSPE;
use App\Entity\Note;
use App\Entity\User;
use App\Entity\Rappel;
use App\Entity\Contact;
use App\Entity\Contrat;
use App\Entity\GasMeter;
use App\Entity\Entreprise;
use App\Entity\EspaceClient;
use App\Entity\ElectricMeter;
use App\Form\EntrepriseType;
use App\Form\ContratType;
use App\Form\UserEntrepriseType;
use App\Service\PricingService;
use App\Repository\EntrepriseRepository;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Psr\Log\LoggerInterface;
class EntrepriseController extends AbstractController
{
private $pricingService;
private $logger;
public function __construct(PricingService $pricingService, LoggerInterface $logger)
{
$this->pricingService = $pricingService;
$this->logger = $logger;
}
/**
* @Route("/entreprise", name="app_entreprise")
*/
// ...
public function index(ManagerRegistry $doctrine): Response
{
$em = $doctrine->getManager();
// ---- ENTREPRISES ----
/** @var Entreprise[] $entreprises */
$entreprises = $em->getRepository(Entreprise::class)->findAll();
$entrepriseIds = array_map(fn($e)=>$e->getId(), $entreprises);
// Map Entreprise -> Users
$allUserIds = [];
foreach ($entreprises as $e) {
foreach ((array)$e->getUtilisateur() as $uid) {
if ($uid !== null && $uid !== '') $allUserIds[(int)$uid] = true;
$eid = $e->getId();
}
}
$allUserIds = array_keys($allUserIds);
$usersById = [];
if ($allUserIds) {
$users = $em->createQueryBuilder()
->select('u.id, u.username')
->from(User::class, 'u')
->where('u.id IN (:ids)')->setParameter('ids', $allUserIds)
->getQuery()->getArrayResult();
foreach ($users as $u) {
$usersById[(int)$u['id']] = $u['username'];
}
}
// Contacts pour toutes les entreprises en 1 requête
$contactsByEntreprise = [];
if ($entrepriseIds) {
$rows = $em->createQueryBuilder()
->select('c.entreprise_id AS eid, c.nom AS nom, c.prenom AS prenom')
->from(Contact::class, 'c')
->where('c.entreprise_id IN (:ids)')->setParameter('ids', $entrepriseIds)
->getQuery()->getArrayResult();
foreach ($rows as $r) {
$eid = (int)$r['eid'];
$contactsByEntreprise[$eid][] = trim(($r['nom'] ?? '').' '.($r['prenom'] ?? ''));
}
}
// Compteurs élec/gaz pour toutes les entreprises en 2 requêtes
$elecByEntreprise = $gazByEntreprise = [];
$electricMeters = $em->createQueryBuilder()
->select('em.entreprise_id AS eid, em.PDL AS pdl')
->from(ElectricMeter::class, 'em')
->where('em.entreprise_id IN (:ids)')->setParameter('ids',$entrepriseIds)
->getQuery()->getArrayResult();
foreach ($electricMeters as $r) {
$elecByEntreprise[(int)$r['eid']][] = $r['pdl'];
}
$gasMeters = $em->createQueryBuilder()
->select('gm.entreprise_id AS eid, gm.PDL AS pdl')
->from(GasMeter::class, 'gm')
->where('gm.entreprise_id IN (:ids)')->setParameter('ids',$entrepriseIds)
->getQuery()->getArrayResult();
foreach ($gasMeters as $r) {
$gazByEntreprise[(int)$r['eid']][] = $r['pdl'];
}
// Construire le tableau ENTREPRISES
$array_entreprises = [];
foreach ($entreprises as $e) {
$eid = $e->getId();
$usernames = [];
foreach ((array)$e->getUtilisateur() as $uid) {
$uid = (int)$uid;
if (isset($usersById[$uid])) $usernames[] = $usersById[$uid];
}
$entreprise_contacts = isset($contactsByEntreprise[$eid]) ? implode(' ', $contactsByEntreprise[$eid]) : '';
$allPdls = implode(' ', array_merge($elecByEntreprise[$eid] ?? [], $gazByEntreprise[$eid] ?? []));
$array_entreprises[] = [
$e->getRaisonSociale(),
$e->getCommune(),
$e->getSiret(),
$entreprise_contacts,
implode(', ', $usernames),
'<div class="d-flex justify-content-center gap-2">
<a href="'.$this->generateUrl('app_entreprise_details',['id' => $eid]).'" class="btn btn-sm btn-primary"><i class="fa-solid fa-eye"></i></a>
<a href="'.$this->generateUrl('app_entreprise_edit',['id' => $eid]).'" class="btn btn-sm btn-warning"><i class="fa-solid fa-screwdriver-wrench"></i></a>
<a href="'.$this->generateUrl('app_entreprise_suppr',['id' => $eid]).'" class="btn btn-sm btn-danger"><i class="fa-solid fa-trash"></i></a>
</div>',
$allPdls,
$e->getNaf(),
$eid,
];
}
// ---- CONTRATS ----
/** @var Contrat[] $contrats */
$contrats = $em->getRepository(Contrat::class)->findAll();
// Préparer détection type (liste PDL elec/gaz en 2 requêtes scalaires)
$electricPDLs = array_column(
$em->createQueryBuilder()->select('em.PDL AS p')->from(ElectricMeter::class,'em')->getQuery()->getScalarResult(),
'p'
);
$gasPDLs = array_column(
$em->createQueryBuilder()->select('gm.PDL AS p')->from(GasMeter::class,'gm')->getQuery()->getScalarResult(),
'p'
);
$isElec = array_fill_keys($electricPDLs, true);
$isGaz = array_fill_keys($gasPDLs, true);
// ---- PDLs (élec/gaz) + last contrat pour CHAQUE PDL en 1 requête ----
// 1) récupérer tous les PDL connus des compteurs
$allMeterPDLs = array_merge($electricPDLs, $gasPDLs);
$allMeterPDLs = array_values(array_unique(array_filter($allMeterPDLs)));
// Map Entreprise (id => raison sociale) pour éviter des find()
$rsById = [];
foreach ($entreprises as $e) { $rsById[$e->getId()] = $e->getRaisonSociale(); }
// 2) récupérer TOUS les contrats pour ces PDL, triés pdl, dateDebut DESC
$contractsByPdl = [];
$lastContratByPdl = [];
if ($allMeterPDLs) {
$allC = $em->createQueryBuilder()
->select('c.id, c.pdl, c.date_debut AS dateDebut, c.date_fin AS dateFin, c.fournisseur, e.id AS eid')
->from(Contrat::class, 'c')
->leftJoin('c.entreprise', 'e')
->where('c.pdl IN (:pdls)')->setParameter('pdls', $allMeterPDLs)
->orderBy('c.pdl', 'ASC')
->addOrderBy('c.date_debut', 'DESC')
->getQuery()->getArrayResult();
foreach ($allC as $row) {
$p = (string)$row['pdl'];
$eid = $row['eid'] ?? null;
$cid = isset($row['id']) ? (int)$row['id'] : null;
$contractsByPdl[$p][] = [
'id' => (int)$row['id'],
'entreprise' => $eid && isset($rsById[$eid]) ? $rsById[$eid] : 'entreprise supprimée',
'eid' => $eid,
'dateDebut' => $row['dateDebut'] instanceof \DateTimeInterface ? $row['dateDebut']->format('d/m/Y') : '',
'dateFin' => $row['dateFin'] instanceof \DateTimeInterface ? $row['dateFin']->format('d/m/Y') : '',
'fournisseur' => $row['fournisseur'] ?? '',
'viewUrl' => $eid ? $this->generateUrl('app_entreprise_details', ['id' => $eid]) : null,
'editUrl' => ($eid && $cid) ? $this->generateUrl('app_entreprise_edit_contrat', [
'entrepriseId' => $eid, 'id' => $cid
]) : null,
'deleteUrl' => ($eid && $cid) ? $this->generateUrl('app_entreprise_delete_contrat', [
'entrepriseId' => $eid, 'id' => $cid
]) : null,
];
// Mémoriser le plus récent par PDL (premier vu car trié date_debut DESC)
if (!isset($lastContratByPdl[$p])) {
$lastContratByPdl[$p] = $row;
}
}
}
// Table CONTRATS (pas de continue: on garde "entreprise supprimée")
$array_contrats = [];
foreach ($contrats as $contrat) {
$ent = $contrat->getEntreprise();
$raisonSociale = $ent ? ($rsById[$ent->getId()] ?? 'entreprise supprimée') : 'entreprise supprimée';
$pdl = $contrat->getPdl();
$profil = ''; $fournisseur = $contrat->getFournisseur() ?? '';
// On essaye de prendre profil/fournisseur depuis compteur si besoin (optionnel)
if ($pdl) {
if (isset($isElec[$pdl])) {
// si tu veux enrichir, fais-le par requête groupée comme plus haut
} elseif (isset($isGaz[$pdl])) {
// idem
}
}
// Pastille statut
$dateFin = $contrat->getDateFin();
if (!$dateFin) {
$statut = '<span class="status-dot status-blue"></span>';
} else {
$daysRemaining = (int)((new \DateTime())->diff($dateFin))->format('%r%a');
$class = $daysRemaining > 180 ? 'status-green' : ($daysRemaining > 90 ? 'status-orange' : 'status-red');
$statut = '<span class="status-dot '.$class.'"></span>';
}
// Type contrat via PDL
$type = $pdl ? (isset($isElec[$pdl]) ? 'elec' : (isset($isGaz[$pdl]) ? 'gaz' : '')) : '';
$actionButtons = ($ent)
? '<div class="d-flex justify-content-center gap-2">
<a href="'.$this->generateUrl('app_entreprise_edit_contrat', [
'entrepriseId' => $ent->getId(),
'id' => $contrat->getId()
]).'" class="btn btn-sm btn-warning" title="Modifier"><i class="fa-solid fa-screwdriver-wrench"></i></a>
<a href="'.$this->generateUrl('app_entreprise_delete_contrat', [
'entrepriseId' => $ent->getId(),
'id' => $contrat->getId()
]).'" class="btn btn-sm btn-danger" title="Supprimer"><i class="fa-solid fa-trash"></i></a>
</div>'
: '';
$array_contrats[] = [
$raisonSociale,
$contrat->getDateDebut() ? $contrat->getDateDebut()->format('d/m/Y') : null,
$contrat->getDateFin() ? $contrat->getDateFin()->format('d/m/Y') : null,
$profil,
$fournisseur,
$statut,
$actionButtons,
$type
];
}
// ---- PDLs ÉLECTRIQUES ----
$elecFull = $em->createQueryBuilder()
->select('
em.id,
em.entreprise_id AS eid,
em.adresse_compteur AS adresseCompteur,
em.PDL,
em.date_debut AS dateDebut,
em.date_fin AS dateFin,
em.Profil AS profil,
em.CAR,
em.fournisseur,
em.prix
')
->from(ElectricMeter::class, 'em')
->getQuery()->getArrayResult();
$pdls_elec = [];
foreach ($elecFull as $m) {
$eid = (int)$m['eid'];
$last = $lastContratByPdl[$m['PDL']] ?? null;
$lastFin = null;
if ($last && !empty($last['dateFin'])) $lastFin = $last['dateFin'];
elseif (!empty($m['dateFin'])) $lastFin = $m['dateFin'];
$statut = '<span class="status-dot status-blue"></span>';
if ($lastFin instanceof \DateTimeInterface) {
$dRest = (int)((new \DateTime())->diff($lastFin))->format('%r%a');
$class = $dRest > 180 ? 'status-green' : ($dRest > 90 ? 'status-orange' : 'status-red');
$statut = '<span class="status-dot '.$class.'"></span>';
}
$actionButtons =
'<div class="d-flex justify-content-center gap-2">
<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>
<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>
</div>';
$pdls_elec[] = [
$rsById[$eid] ?? '',
$m['adresseCompteur'],
$m['PDL'],
$m['dateDebut'] instanceof \DateTimeInterface ? $m['dateDebut']->format('d/m/Y') : '',
$lastFin instanceof \DateTimeInterface ? $lastFin->format('d/m/Y') : '',
$statut,
$m['profil'],
$m['CAR'],
$last['fournisseur'] ?? $m['fournisseur'] ?? '',
$m['prix'],
$actionButtons,
];
}
// ---- PDLs GAZ ----
$gazFull = $em->createQueryBuilder()
->select('
gm.id,
gm.entreprise_id AS eid,
gm.adresse_compteur AS adresseCompteur,
gm.PDL,
gm.date_debut AS dateDebut,
gm.date_fin AS dateFin,
gm.profil AS profil,
gm.CAR,
gm.fournisseur,
gm.prix
')
->from(GasMeter::class, 'gm')
->getQuery()->getArrayResult();
$pdls_gaz = [];
foreach ($gazFull as $m) {
$eid = (int)$m['eid'];
$last = $lastContratByPdl[$m['PDL']] ?? null;
$lastFin = null;
if ($last && !empty($last['dateFin'])) $lastFin = $last['dateFin'];
elseif (!empty($m['dateFin'])) $lastFin = $m['dateFin'];
$statut = '<span class="status-dot status-blue"></span>';
if ($lastFin instanceof \DateTimeInterface) {
$dRest = (int)((new \DateTime())->diff($lastFin))->format('%r%a');
$class = $dRest > 180 ? 'status-green' : ($dRest > 90 ? 'status-orange' : 'status-red');
$statut = '<span class="status-dot '.$class.'"></span>';
}
$actionButtons =
'<div class="d-flex justify-content-center gap-2">
<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>
<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>
</div>';
$pdls_gaz[] = [
$rsById[$eid] ?? '',
$m['adresseCompteur'],
$m['PDL'],
$m['dateDebut'] instanceof \DateTimeInterface ? $m['dateDebut']->format('d/m/Y') : '',
$lastFin instanceof \DateTimeInterface ? $lastFin->format('d/m/Y') : '',
$statut,
$m['profil'],
$m['CAR'],
$last['fournisseur'] ?? $m['fournisseur'] ?? '',
$m['prix'],
$actionButtons,
];
}
// ---- INTERVALLES DE CONTRATS PAR ENTREPRISE (INDEX DE MOIS) ----
// Axe fixe : 2010-01 -> 2050-12
$ORIGIN = new \DateTime('2010-01-01 00:00:00');
$END = new \DateTime('2050-12-31 00:00:00');
// Liste PDL gaz déjà dispo plus haut : $isGaz (array_flip des PDL gaz)
$companyMonthIntervals = []; // [eid => [[mStart, mEnd], ...] inclusifs]
/**
* Convertit une date -> index de mois depuis 2010-01 (0 = 2010-01).
*/
$monthIndex = function(\DateTimeInterface $d): int {
$y = (int)$d->format('Y');
$m = (int)$d->format('n'); // 1..12
return ($y - 2010) * 12 + ($m - 1);
};
// Bornes de coupe
$minIndex = $monthIndex($ORIGIN);
$maxIndex = $monthIndex($END);
foreach ($contrats as $contrat) {
$ent = $contrat->getEntreprise();
if (!$ent) { continue; }
$start = $contrat->getDateDebut();
$end = $contrat->getDateFin();
if (!$start) { continue; } // sans début => on ignore
$start = (clone $start)->setTime(0,0,0);
// Gaz : +1 jour sur la date de début
$pdl = $contrat->getPdl();
if ($pdl && isset($isGaz[$pdl])) {
$start->modify('+1 day');
}
// Fin ouverte => on borne à END
$end = $end ? (clone $end)->setTime(0,0,0) : clone $END;
// Clamp aux bornes 2010-01..2050-12
if ($end < $ORIGIN || $start > $END) { continue; }
if ($start < $ORIGIN) { $start = clone $ORIGIN; }
if ($end > $END) { $end = clone $END; }
$mA = $monthIndex($start);
$mB = $monthIndex($end);
// inclusif : si même mois début/fin, l’intervalle couvre ce mois
if ($mA > $mB) { continue; }
$eid = $ent->getId();
$companyMonthIntervals[$eid][] = [$mA, $mB];
}
// Fusion par entreprise (tri + merge des contigus)
foreach ($companyMonthIntervals as $eid => $list) {
if (!$list) continue;
usort($list, fn($x,$y) => $x[0] <=> $y[0]);
$merged = [];
[$a,$b] = $list[0];
foreach ($list as [$x,$y]) {
// contigu si x <= b+1 (mois adjacents)
if ($x <= $b + 1) {
if ($y > $b) $b = $y;
} else {
$merged[] = [$a,$b];
[$a,$b] = [$x,$y];
}
}
$merged[] = [$a,$b];
$companyMonthIntervals[$eid] = $merged;
}
// Infos axe fixe
$originYear = 2010;
$originMonth = 1; // janvier
$endYear = 2050;
$endMonth = 12;
$totalMonths = ($endYear - $originYear) * 12 + ($endMonth - $originMonth + 1); // inclusif
return $this->render('entreprise/index.html.twig', [
'entreprises' => $array_entreprises,
'contrats' => $array_contrats,
'pdls_elec' => $pdls_elec,
'pdls_gaz' => $pdls_gaz,
'contracts_by_pdl' => $contractsByPdl,
// Axe temporel fixe en mois
'origin_year' => $originYear,
'origin_month' => $originMonth,
'total_months' => $totalMonths, // ex: (2010-01 .. 2050-12) = 492 mois
// Intervalles fusionnés par entreprise (indices de mois)
'merged_month_intervals' => $companyMonthIntervals,
]);
}
/**
* @Route("/entreprise/calculate-value", name="app_entreprise_calculate_value", methods={"POST"})
*/
public function calculateValue(Request $request, ManagerRegistry $doctrine): JsonResponse
{
$this->logger->debug('Received calculate value request', [
'car' => $request->request->get('car'),
'dateDebut' => $request->request->get('dateDebut'),
'dateFin' => $request->request->get('dateFin'),
'pdl' => $request->request->get('pdl'),
'raw_request' => $request->request->all()
]);
// Validate CSRF token
$submittedToken = $request->headers->get('X-CSRF-Token');
if (!$this->isCsrfTokenValid('calculate-value', $submittedToken)) {
$this->logger->error('Invalid CSRF token');
return new JsonResponse(['error' => 'Invalid CSRF token'], 403);
}
try {
$car = floatval($request->request->get('car'));
if ($car <= 0) {
throw new \InvalidArgumentException('CAR must be greater than 0');
}
// Parse dates and set time to start of day
$dateDebut = new \DateTime($request->request->get('dateDebut'));
$dateDebut->setTime(0, 0, 0);
$dateFin = new \DateTime($request->request->get('dateFin'));
$dateFin->setTime(0, 0, 0);
if ($dateDebut > $dateFin) {
throw new \InvalidArgumentException('Start date must be before end date');
}
// Check if this is a gas contract by looking up the PDL
$pdl = $request->request->get('pdl');
$isGasContract = false;
if ($pdl) {
$gasMeter = $doctrine->getRepository(GasMeter::class)->findOneBy(['PDL' => $pdl]);
if ($gasMeter) {
$isGasContract = true;
// For gas contracts, adjust the start date
$dateDebut->modify('+1 day');
}
}
// Create a temporary contract object to calculate the value
$contrat = new Contrat();
$contrat->setCar($car);
$contrat->setDateDebut($dateDebut);
$contrat->setDateFin($dateFin);
if ($pdl) {
$contrat->setPdl($pdl);
}
// Calculate the annual value using the pricing service
$value = $this->pricingService->calculateAnnualValue($contrat);
$this->logger->debug('Calculated contract value', [
'car' => $car,
'dateDebut' => $dateDebut->format('d/m/Y'),
'dateFin' => $dateFin->format('d/m/Y'),
'isGasContract' => $isGasContract,
'value' => $value
]);
return new JsonResponse([
'value' => $value,
'debug' => [
'car' => $car,
'dateDebut' => $dateDebut->format('d/m/Y'),
'dateFin' => $dateFin->format('d/m/Y'),
'isGasContract' => $isGasContract
]
]);
} catch (\Exception $e) {
$this->logger->error('Error calculating contract value', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return new JsonResponse(['error' => 'Error calculating value: ' . $e->getMessage()], 500);
}
}
/**
* @Route("/entreprise/add", name="app_entreprise_add")
*/
public function add(Request $request, EntityManagerInterface $entityManager): Response
{
$entreprises = new Entreprise();
// using createQueryBuilder
$utilisateurs = $entityManager->createQueryBuilder()
->select('u')
->from(User::class, 'u')
->where('u.roles LIKE :roles')
->setParameter('roles', '%ROLE_TEAM%')
->getQuery()
->getResult();
$array_utilisateurs = array();
for ($i=0; $i < count($utilisateurs); $i++) {
$array_utilisateurs[$utilisateurs[$i]->getUsername()] = $utilisateurs[$i]->getId();
}
$form = $this->createForm(EntrepriseType::class, $entreprises, ['utilisateurs' => $array_utilisateurs]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($entreprises);
$entityManager->flush();
return $this->redirectToRoute('app_entreprise');
}
return $this->render('entreprise/add.html.twig', [
'entrepriseForm' => $form->createView(),
'array_utilisateurs' => $array_utilisateurs,
]);
}
/**
* @Route("/entreprise/edit/{id}", name="app_entreprise_edit")
*/
public function edit(int $id, Request $request, EntityManagerInterface $entityManager, ManagerRegistry $doctrine): Response
{
$entreprise = $doctrine->getRepository(Entreprise::class)->findOneBy(['id' => $id]);
$utilisateurs = $entityManager->createQueryBuilder()
->select('u')
->from(User::class, 'u')
->where('u.roles LIKE :roles')
->setParameter('roles', '%ROLE_TEAM%')
->getQuery()
->getResult();
$array_utilisateurs = array();
for ($i=0; $i < count($utilisateurs); $i++) {
$array_utilisateurs[$utilisateurs[$i]->getUsername()] = $utilisateurs[$i]->getId();
}
$form = $this->createForm(EntrepriseType::class, $entreprise, ['utilisateurs' => $array_utilisateurs]);
$form->handleRequest($request);
$entreprise_entity = [ 'raison_sociale' => $entreprise->getRaisonSociale(),
'siret' => $entreprise->getSiret(),
'naf' => $entreprise->getNaf(),
'rcs' => $entreprise->getRcs(),
'num_voie' => $entreprise->getNumVoie(),
'adresse' => $entreprise->getAdresse(),
'code_postal' => $entreprise->getCodePostal(),
'commune' => $entreprise->getCommune(),
'code_insee' => $entreprise->getCodeInsee(),
'statut' => $entreprise->getStatut(),
'utilisateur' => $entreprise->getUtilisateur(),
];
if ($form->isSubmitted() && $form->isValid()) {
$entreprisesEdit = $form->getData();
if($entreprisesEdit->getRaisonSociale() != null){
$entreprise->setRaisonSociale($entreprisesEdit->getRaisonSociale());
}
if($entreprisesEdit->getSiret() != null){
$entreprise->setSiret($entreprisesEdit->getSiret());
}
if($entreprisesEdit->getNaf() != null){
$entreprise->setNaf($entreprisesEdit->getNaf());
}
if($entreprisesEdit->getRcs() != null){
$entreprise->setRcs($entreprisesEdit->getRcs());
}
if($entreprisesEdit->getNumVoie() != null){
$entreprise->setNumVoie($entreprisesEdit->getNumVoie());
}
if($entreprisesEdit->getAdresse() != null){
$entreprise->setAdresse($entreprisesEdit->getAdresse());
}
if($entreprisesEdit->getCodePostal() != null){
$entreprise->setCodePostal($entreprisesEdit->getCodePostal());
}
if($entreprisesEdit->getCommune() != null){
$entreprise->setCommune($entreprisesEdit->getCommune());
}
if($entreprisesEdit->getCodeInsee() != null){
$entreprise->setCodeInsee($entreprisesEdit->getCodeInsee());
}
if($entreprisesEdit->getStatut() != null){
$entreprise->setStatut($entreprisesEdit->getStatut());
}
if($entreprisesEdit->getUtilisateur() != null){
$entreprise->setUtilisateur(array_map('strval', $entreprisesEdit->getUtilisateur()));
}
$entityManager->persist($entreprise);
$entityManager->flush();
return $this->redirectToRoute('app_entreprise');
}
return $this->render('entreprise/edit.html.twig', [
'entrepriseForm' => $form->createView(),
'entreprise' => $entreprise_entity
]);
}
/**
* @Route("/entreprise/suppr/{id}", name="app_entreprise_suppr")
*/
public function suppr(int $id, Request $request, EntityManagerInterface $entityManager, ManagerRegistry $doctrine): Response
{
$notes = $doctrine->getRepository(Note::class)->findBy(['entreprise_id' => $id]);
for ($i=0; $i < count($notes); $i++) {
$entityManager->remove($notes[$i]);
$entityManager->flush();
};
$rappels = $doctrine->getRepository(Rappel::class)->findBy(['entreprise_id' => $id]);
for ($i=0; $i < count($rappels); $i++) {
$entityManager->remove($rappels[$i]);
$entityManager->flush();
};
$electric_meters = $doctrine->getRepository(ElectricMeter::class)->findBy(['entreprise_id' => $id]);
for ($i=0; $i < count($electric_meters); $i++) {
$entityManager->remove($electric_meters[$i]);
$entityManager->flush();
};
$gas_meters = $doctrine->getRepository(GasMeter::class)->findBy(['entreprise_id' => $id]);
for ($i=0; $i < count($gas_meters); $i++) {
$entityManager->remove($gas_meters[$i]);
$entityManager->flush();
};
$cspes = $doctrine->getRepository(CSPE::class)->findBy(['entreprise_id' => $id]);
for ($i=0; $i < count($cspes); $i++) {
$entityManager->remove($cspes[$i]);
$entityManager->flush();
};
$espace_clients = $doctrine->getRepository(EspaceClient::class)->findBy(['entreprise_id' => $id]);
for ($i=0; $i < count($espace_clients); $i++) {
$entityManager->remove($espace_clients[$i]);
$entityManager->flush();
};
$contacts = $doctrine->getRepository(Contact::class)->findBy(['entreprise_id' => $id]);
for ($i=0; $i < count($contacts); $i++) {
$entityManager->remove($contacts[$i]);
$entityManager->flush();
};
$entreprise = $doctrine->getRepository(Entreprise::class)->findOneBy(['id' => $id]);
$entityManager->remove($entreprise);
$entityManager->flush();
return $this->redirectToRoute('app_entreprise');
}
/**
* @Route("/entreprise/details/{id}", name="app_entreprise_details")
*/
public function details(int $id, ManagerRegistry $doctrine): Response
{
$entreprise = $doctrine->getRepository(Entreprise::class)->findOneBy(['id' => $id]);
if(!$entreprise){
return $this->redirectToRoute('app_requetes');
}
// Get all users for this company
$userIds = $entreprise->getUtilisateur();
$user_names = [];
if (!empty($userIds)) {
foreach ($userIds as $userId) {
$user = $doctrine->getRepository(User::class)->find((int)$userId);
if ($user) {
$user_names[] = $user->getUsername();
}
}
}
$user_name = implode(', ', $user_names);
$entreprise_entity = [ 'id' => $entreprise->getId(),
'raison_sociale' => $entreprise->getRaisonSociale(),
'siret' => $entreprise->getSiret(),
'naf' => $entreprise->getNaf(),
'rcs' => $entreprise->getRcs(),
'num_voie' => $entreprise->getNumVoie(),
'adresse' => $entreprise->getAdresse(),
'code_postal' => $entreprise->getCodePostal(),
'commune' => $entreprise->getCommune(),
'code_insee' => $entreprise->getCodeInsee(),
'statut' => $entreprise->getStatut(),
'utilisateur' => $user_names,
];
// Fetch and prepare notes data
$notes = $doctrine->getRepository(Note::class)->findBy(['entreprise_id' => $id], ['date_creation' => 'DESC']);
$array_notes = array();
foreach ($notes as $note) {
$user = $note->getUser();
$array_notes[] = [
'date_creation' => $note->getDateCreation() ? $note->getDateCreation()->format('d/m/Y') : '',
'texte' => $note->getTexte(),
'user' => $user ? $user->getUsername() : 'Non défini',
'edit_url' => $this->generateUrl('app_note_edit', ['id' => $note->getId()]),
'delete_url' => $this->generateUrl('app_note_suppr', ['id' => $note->getId()]),
];
}
// Fetch and prepare rappels data
$rappels = $doctrine->getRepository(Rappel::class)->findBy(['entreprise_id' => $id]);
$array_rappels = array();
foreach ($rappels as $rappel) {
$array_rappels[] = [
$rappel->getTitre(),
$rappel->getDescription(),
$rappel->getEcheance()->format('d/m/Y'),
$rappel->isCompleter(),
'<a href="'.$this->generateUrl('app_rappel_edit',['id' => $rappel->getId()]).'" type="button" class="btn btn-sm btn-primary mb-1">Modifier</a>
<a href="'.$this->generateUrl('app_rappel_suppr',['id' => $rappel->getId()]).'" type="button" class="btn btn-sm btn-danger ">Supprimer</a>',
];
}
// Fetch electric meters and their PDLs
$electric_meters = $doctrine->getRepository(ElectricMeter::class)->findBy(['entreprise_id' => $id]);
$array_electric_meters = array_map(function($meter) {
return [
'pdl' => $meter->getPDL(),
'id' => $meter->getId(),
];
}, $electric_meters);
$electric_pdls = array_map(function($meter) {
return $meter->getPDL();
}, $electric_meters);
// Fetch gas meters and their PDLs
$gas_meters = $doctrine->getRepository(GasMeter::class)->findBy(['entreprise_id' => $id]);
$array_gas_meters = array_map(function($meter) {
return [
'pdl' => $meter->getPDL(),
'id' => $meter->getId(),
];
}, $gas_meters);
$gas_pdls = array_map(function($meter) {
return $meter->getPDL();
}, $gas_meters);
$cspes = $doctrine->getRepository(CSPE::class)->findBy(['entreprise_id' => $id]);
$array_cspes = array();
for ($i=0; $i < count($cspes); $i++) {
$array_cspes[$i] = [
$cspes[$i]->getNotes(),
date_format($cspes[$i]->getDate(),'d/m/Y'),
$cspes[$i]->getValeur(),
'<a href="'.$this->generateUrl('app_cspe_edit',['id' => $cspes[$i]->getId()]).'" type="button" class="btn btn-sm btn-warning mb-1">Modifier</a>
<a href="'.$this->generateUrl('app_cspe_suppr',['id' => $cspes[$i]->getId()]).'" type="button" class="btn btn-sm btn-danger ">Supprimer</a>',
];
};
$espace_clients = $doctrine->getRepository(EspaceClient::class)->findBy(['entreprise_id' => $id]);
$array_espace_clients = array();
for ($i=0; $i < count($espace_clients); $i++) {
$lien = $espace_clients[$i]->getLien();
// Add http:// if no protocol specified
if (!preg_match("~^(?:f|ht)tps?://~i", $lien)) {
$lien = "http://" . $lien;
}
// Extract domain name for button text
$domain = parse_url($lien, PHP_URL_HOST) ?: $lien;
$domainParts = explode('.', $domain);
$buttonText = count($domainParts) > 1 ? $domainParts[1] : $domain;
$array_espace_clients[$i] = [
$espace_clients[$i]->getFournisseur(),
$espace_clients[$i]->getLogin(),
$espace_clients[$i]->getMdp(),
'<a href="'.$lien.'" target="_blank" type="button" class="btn btn-primary">'.$buttonText.'</a>',
'<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>
<a href="'.$this->generateUrl('app_espace_client_suppr',['id' => $espace_clients[$i]->getId()]).'" type="button" class="btn btn-sm btn-danger ">Supprimer</a>',
];
};
$contacts = $doctrine->getRepository(Contact::class)->findBy(['entreprise_id' => $id]);
$array_contacts = array();
for ($i=0; $i < count($contacts); $i++) {
$array_contacts[$i] = [
$contacts[$i]->getNom(),
$contacts[$i]->getPrenom(),
$contacts[$i]->getCivilite(),
$contacts[$i]->getFonction(),
$contacts[$i]->getFixe(),
$contacts[$i]->getEmail(),
$contacts[$i]->getPortable(),
'<a href="'.$this->generateUrl('app_contact_edit',['id' => $contacts[$i]->getId()]).'" type="button" class="btn btn-sm btn-warning mb-1">Modifier</a>
<a href="'.$this->generateUrl('app_contact_suppr',['id' => $contacts[$i]->getId()]).'" type="button" class="btn btn-sm btn-danger ">Supprimer</a>',
];
};
$contrats = $doctrine->getRepository(Contrat::class)->findBy(['entreprise' => $entreprise]);
$array_contrats = array();
foreach ($contrats as $contrat) {
$array_contrats[] = [
"id" => $contrat->getId(),
"duree" => $contrat->getDuree(),
"valeur" => $contrat->getValeur(),
"pdl" => $contrat->getPdl(),
"car" => $contrat->getCar(),
"prix_moyen" => $contrat->getPrixMoyen(),
"fournisseur" => $contrat->getFournisseur(),
"date_debut" => $contrat->getDateDebut() ? $contrat->getDateDebut()->format('d/m/Y') : '',
"date_fin" => $contrat->getDateFin() ? $contrat->getDateFin()->format('d/m/Y') : '',
"date_signature" => $contrat->getDateSignature() ? $contrat->getDateSignature()->format('d/m/Y') : '',
'<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>
<a href="'.$this->generateUrl('app_entreprise_delete_contrat', ['entrepriseId' => $entreprise->getId(), 'id' => $contrat->getId()]).'" type="button" class="btn btn-sm btn-danger">Supprimer</a>',
];
}
return $this->render('entreprise/details.html.twig', [
'entreprise' => $entreprise_entity,
'notes' => $array_notes,
'rappels' => $array_rappels,
'electric_meters' => $array_electric_meters,
'gas_meters' => $array_gas_meters,
'electric_pdls' => $electric_pdls,
'gas_pdls' => $gas_pdls,
'cspes' => $array_cspes,
'espace_clients' => $array_espace_clients,
'contacts' => $array_contacts,
'contrats' => $array_contrats,
]);
}
/**
* @Route("/entreprise/electric_meter/details/{id}", name="app_electric_meter_details")
*/
public function electricMeterDetails(Request $request, int $id, ManagerRegistry $doctrine): JsonResponse
{
$pdl = $request->query->get('pdl');
if (!$pdl) {
return new JsonResponse(['error' => 'PDL parameter is required'], 400);
}
// First verify the entreprise exists
$entreprise = $doctrine->getRepository(Entreprise::class)->find($id);
if (!$entreprise) {
return new JsonResponse(['error' => 'Entreprise not found'], 404);
}
// Find the electric meter using standard findOneBy method
$electricMeter = $doctrine->getRepository(ElectricMeter::class)->findOneBy([
'entreprise_id' => $id,
'PDL' => $pdl
]);
if (!$electricMeter) {
return new JsonResponse(['error' => 'Electric meter not found'], 404);
}
$meterDetails = [
'adresseCompteur' => $electricMeter->getAdresseCompteur(),
'PDL' => $electricMeter->getPDL(),
'dateDebut' => $electricMeter->getDateDebut() ? $electricMeter->getDateDebut()->format('d/m/Y') : '',
'dateFin' => $electricMeter->getDateFin() ? $electricMeter->getDateFin()->format('d/m/Y') : '',
'PS' => $electricMeter->getPS(),
'profil' => $electricMeter->getProfil(),
'CAR' => $electricMeter->getCAR(),
'fournisseur' => $electricMeter->getFournisseur(),
'prix' => $electricMeter->getPrix()
];
return new JsonResponse($meterDetails);
}
/**
* @Route("/entreprise/{id}/gas-meter-details", name="app_gas_meter_details")
*/
public function gasMeterDetails(Request $request, int $id, ManagerRegistry $doctrine): JsonResponse
{
$pdl = $request->query->get('pdl');
if (!$pdl) {
return new JsonResponse(['error' => 'PDL parameter is required'], 400);
}
// First verify the entreprise exists
$entreprise = $doctrine->getRepository(Entreprise::class)->find($id);
if (!$entreprise) {
return new JsonResponse(['error' => 'Entreprise not found'], 404);
}
// Find the gas meter using standard findOneBy method
$gasMeter = $doctrine->getRepository(GasMeter::class)->findOneBy([
'entreprise_id' => $id,
'PDL' => $pdl
]);
if (!$gasMeter) {
return new JsonResponse(['error' => 'Gas meter not found'], 404);
}
$meterDetails = [
'adresseCompteur' => $gasMeter->getAdresseCompteur(),
'PDL' => $gasMeter->getPDL(), // Added PDL field
'dateDebut' => $gasMeter->getDateDebut() ? $gasMeter->getDateDebut()->format('d/m/Y') : '',
'dateFin' => $gasMeter->getDateFin() ? $gasMeter->getDateFin()->format('d/m/Y') : '',
'profil' => $gasMeter->getProfil(),
'CAR' => $gasMeter->getCAR(),
'fournisseur' => $gasMeter->getFournisseur(),
'prix' => $gasMeter->getPrix(),
];
return new JsonResponse($meterDetails);
}
/**
* @Route("/entreprise/infoclient", name="app_entreprise_infoclient")
*/
public function infoclient(HttpClientInterface $httpClient): JsonResponse
{
// Utilisez les paramètres appropriés pour votre requête
$url = 'https://api.societe.com/api/v1/infoclient';
$headers = [
'headers' => [
'X-Authorization' => 'socapi 8938e836988619dc20be14360fba30e3',
],
];
// Effectuez la requête
$response = $httpClient->request('GET', $url, $headers);
// Renvoie la réponse JSON
return new JsonResponse($response->toArray());
}
/**
* @Route("/entreprise/info_entreprise/{numero}", name="app_entreprise_info_entreprise")
*/
public function info_entreprise(HttpClientInterface $httpClient, ManagerRegistry $doctrine, $numero): JsonResponse
{
// Vérification que l'entreprise n'est pas déjà enregistré en BDD
$entreprise = $doctrine->getRepository(Entreprise::class)->findOneBy(['Siret' => $numero]);
if($entreprise !=null){
return new JsonResponse("existant");
}
$url = 'https://api.societe.com/api/v1/entreprise/'.$numero.'/infoslegales';
$headers = [
'headers' => [
'X-Authorization' => 'socapi 8938e836988619dc20be14360fba30e3',
],
];
// Effectuez la requête
$response = $httpClient->request('GET', $url, $headers);
// Renvoie la réponse JSON
return new JsonResponse($response->toArray());
}
/**
* @Route("/entreprise/{id}/new-contrat", name="app_entreprise_new_contrat")
*/
public function newContrat(Request $request, EntityManagerInterface $entityManager, ManagerRegistry $doctrine, int $id): Response
{
$entreprise = $doctrine->getRepository(Entreprise::class)->find($id);
if (!$entreprise) {
throw $this->createNotFoundException('Entreprise not found');
}
$contrat = new Contrat();
$contrat->setEntreprise($entreprise);
$meterId = $request->query->get('meterId');
$meterType = $request->query->get('meterType');
if ($meterId && $meterType) {
$meter = null;
if ($meterType === 'electric') {
$meter = $doctrine->getRepository(ElectricMeter::class)->find($meterId);
} elseif ($meterType === 'gas') {
$meter = $doctrine->getRepository(GasMeter::class)->find($meterId);
}
if ($meter) {
$contrat->setPdl($meter->getPDL());
$contrat->setCar($meter->getCAR());
$contrat->setPrixMoyen($meter->getPrix());
$contrat->setFournisseur($meter->getFournisseur());
// For both types, set the dates
$contrat->setDateDebut($meter->getDateDebut());
$contrat->setDateFin($meter->getDateFin());
// Calculate initial duration and value
if ($meter->getDateDebut() && $meter->getDateFin()) {
$dateDebut = $meter->getDateDebut();
if ($dateDebut) {
if ($meterType === 'gas') {
$dateDebut->modify('+1 day');
}
}
$duration = $this->calculateDurationInMonths($dateDebut, $meter->getDateFin());
$contrat->setDuree($duration);
$annualValue = $this->pricingService->calculateAnnualValue($contrat);
$contrat->setValeur($annualValue);
}
}
}
$pdlChoices = $this->getPDLChoicesForEntreprise($doctrine, $entreprise);
$form = $this->createForm(ContratType::class, $contrat, [
'pdl_choices' => $pdlChoices
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Calculate duration in months
$duration = $this->calculateDurationInMonths($contrat->getDateDebut(), $contrat->getDateFin());
$contrat->setDuree($duration);
// Only calculate value if not manually set
$submittedValue = $form->get('valeur')->getData();
if ($submittedValue === null || $submittedValue === 0.0) {
$annualValue = $this->pricingService->calculateAnnualValue($contrat);
$contrat->setValeur($annualValue);
}
// Get the first user as the collaborateur (maintain backward compatibility)
$userIds = $entreprise->getUtilisateur();
if (!empty($userIds)) {
$user = $doctrine->getRepository(User::class)->find((int)$userIds[0]);
if ($user) {
$contrat->setCollaborateur($user);
}
}
$entityManager->persist($contrat);
$entityManager->flush();
if ($request->isXmlHttpRequest()) {
return new JsonResponse([
'success' => true,
'contractId' => $contrat->getId(),
'message' => 'Le contrat a été créé avec succès.'
]);
}
return $this->redirectToRoute('app_entreprise_details', ['id' => $entreprise->getId()]);
}
return $this->render('entreprise/new_contrat.html.twig', [
'entreprise' => $entreprise,
'form' => $form->createView(),
]);
}
/**
* @Route("/entreprise/{entrepriseId}/edit-contrat/{id}", name="app_entreprise_edit_contrat")
*/
public function editContrat(Request $request, EntityManagerInterface $entityManager, ManagerRegistry $doctrine, int $entrepriseId, int $id): Response
{
$entreprise = $doctrine->getRepository(Entreprise::class)->find($entrepriseId);
$contrat = $doctrine->getRepository(Contrat::class)->find($id);
if (!$entreprise) {
throw $this->createNotFoundException('Entreprise not found');
}
if (!$contrat) {
throw $this->createNotFoundException('Contrat not found');
}
// Determine if this is a gas contract
$isGasContract = false;
$gasMeter = $doctrine->getRepository(GasMeter::class)->findOneBy([
'entreprise_id' => $entrepriseId,
'PDL' => $contrat->getPdl()
]);
if ($gasMeter) {
$isGasContract = true;
}
// S'assurer que l'entreprise est définie sur le contrat
$contrat->setEntreprise($entreprise);
$pdlChoices = $this->getPDLChoicesForEntreprise($doctrine, $entreprise);
$form = $this->createForm(ContratType::class, $contrat, [
'pdl_choices' => $pdlChoices
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// S'assurer que l'entreprise est toujours définie après la soumission du formulaire
$contrat->setEntreprise($entreprise);
// For gas contracts, ensure the start date is adjusted
$dateDebut = $contrat->getDateDebut();
if ($dateDebut) {
if ($isGasContract) {
$dateDebut->modify('+1 day');
}
}
// Recalculate duration in months
$duration = $this->calculateDurationInMonths($dateDebut, $contrat->getDateFin());
$contrat->setDuree($duration);
// Only calculate value if not manually set
$submittedValue = $form->get('valeur')->getData();
if ($submittedValue === null || $submittedValue === 0.0) {
$annualValue = $this->pricingService->calculateAnnualValue($contrat);
$contrat->setValeur($annualValue);
}
$entityManager->flush();
return $this->redirectToRoute('app_entreprise_details', ['id' => $entreprise->getId()]);
}
return $this->render('entreprise/edit_contrat.html.twig', [
'entreprise' => $entreprise,
'contrat' => $contrat,
'form' => $form->createView(),
]);
}
/**
* @Route("/entreprise/{entrepriseId}/delete-contrat/{id}", name="app_entreprise_delete_contrat")
*/
public function deleteContrat(Request $request, EntityManagerInterface $entityManager, ManagerRegistry $doctrine, int $entrepriseId, int $id): Response
{
$entreprise = $doctrine->getRepository(Entreprise::class)->find($entrepriseId);
$contrat = $doctrine->getRepository(Contrat::class)->find($id);
if (!$entreprise) {
throw $this->createNotFoundException('Entreprise not found');
}
if (!$contrat) {
throw $this->createNotFoundException('Contrat not found');
}
if ($this->isCsrfTokenValid('delete'.$contrat->getId(), $request->request->get('_token'))) {
$entityManager->remove($contrat);
$entityManager->flush();
}
return $this->redirectToRoute('app_entreprise_details', ['id' => $entreprise->getId()]);
}
private function calculateDurationInMonths(?\DateTimeInterface $dateDebut, ?\DateTimeInterface $dateFin): ?int
{
if (!$dateDebut || !$dateFin) {
return null;
}
$interval = $dateDebut->diff($dateFin);
return $interval->y * 12 + $interval->m;
}
private function getPDLChoicesForEntreprise(ManagerRegistry $doctrine, Entreprise $entreprise): array
{
$electricMeters = $doctrine->getRepository(ElectricMeter::class)->findBy(['entreprise_id' => $entreprise->getId()]);
$gasMeters = $doctrine->getRepository(GasMeter::class)->findBy(['entreprise_id' => $entreprise->getId()]);
$pdlChoices = [];
foreach ($electricMeters as $meter) {
$pdlChoices[$meter->getPDL()] = $meter->getPDL();
}
foreach ($gasMeters as $meter) {
$pdlChoices[$meter->getPDL()] = $meter->getPDL();
}
return $pdlChoices;
}
/**
* @Route("/entreprise/associate-user", name="app_entreprise_associate_user")
*/
public function associateUser(Request $request, EntityManagerInterface $entityManager): Response
{
$this->denyAccessUnlessGranted('ROLE_COMPTA');
try {
$form = $this->createForm(UserEntrepriseType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$user = $data['user'];
$entreprises = $data['entreprises'];
// Vérification des données
if (!$user || !$entreprises || empty($entreprises)) {
throw new \InvalidArgumentException('Utilisateur et entreprises sont requis');
}
// Add ROLE_CLIENT_PRO if user doesn't have it
if (!$user->hasRole('ROLE_CLIENT_PRO')) {
$roles = $user->getRoles();
$roles[] = 'ROLE_CLIENT_PRO';
$user->setRoles(array_unique($roles));
}
// Associate user with enterprises
foreach ($entreprises as $entreprise) {
if (!$user->getEntreprises()->contains($entreprise)) {
$user->addEntreprise($entreprise);
$entreprise->addUtilisateur(strval($user->getId()));
}
}
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', sprintf(
'L\'utilisateur %s a été associé avec succès à %d entreprise(s)',
$user->getUsername(),
count($entreprises)
));
return $this->redirectToRoute('app_entreprise');
}
return $this->render('entreprise/associate_user.html.twig', [
'form' => $form->createView(),
]);
} catch (\Exception $e) {
$this->addFlash('error', 'Une erreur est survenue lors de l\'association : ' . $e->getMessage());
return $this->redirectToRoute('app_entreprise_associate_user');
}
}
}