<?php
namespace App\Controller\Front;
use App\Entity\{Service, Devis, Article, WhyChooseUs, AboutUs, User, Client, DevisTravelReason, DevisLuggage, DevisBudget, DevisEquipment, DevisVehicleDetails, DevisAttachment};
use App\Form\{DevisType, ClientType, ClientDevisType};
use App\Repository\{HomepageRepository, ServiceRepository};
use App\Service\{AccessClientService, DistanceCalculator, TransporteurProche, AddressInfoService};
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Form\FormError;
class HomeController extends AbstractController
{
private $distanceCalculator;
private $transporteurProche;
private $tokenStorage;
public function __construct(
DistanceCalculator $distanceCalculator,
TransporteurProche $transporteurProche,
TokenStorageInterface $tokenStorage
)
{
$this->distanceCalculator = $distanceCalculator;
$this->transporteurProche = $transporteurProche;
$this->tokenStorage = $tokenStorage;
}
/**
* @Route("/", name="app_client_home")
*/
public function homepage(
AccessClientService $accessClientService,
HomepageRepository $homepageRepository,
ServiceRepository $serviceRepository,
EntityManagerInterface $entityManager
): Response
{
$accessClientService->handleAccessControl();
$homepage = $homepageRepository->find(1);
$services = $serviceRepository->getCategories('ASC')->getResult();
$lastArticles = $entityManager->getRepository(Article::class)->findBy(['status' => true], ['id' => 'DESC'], 3, 0);
$whyChooseUs = $entityManager->getRepository(WhyChooseUs::class)->findOneBy([], ['id' => 'DESC']);
$aboutUs = $entityManager->getRepository(AboutUs::class)->findOneBySlug('notre-histoire');
return $this->render('front/home/index.html.twig', [
'homepage' => $homepage,
'services' => $services,
'lastArticles' => $lastArticles,
'whyChooseUs' => $whyChooseUs,
'aboutUs' => $aboutUs
]);
}
/**
* @Route("/service/{slug}", name="app_client_service")
*/
public function service(
AccessClientService $accessClientService,
string $slug,
Request $request,
EntityManagerInterface $entityManager,
PaginatorInterface $paginator,
SessionInterface $session
)
{
$accessClientService->handleAccessControl();
$service = $entityManager->getRepository(Service::class)->findOneBy(['slug' => $slug]);
if (!$service) {
throw new NotFoundHttpException('Le service demandé n\'existe pas.');
}
$language = $request->getLocale();
$session->remove('login_info_slug');
$services = $entityManager->getRepository(Service::class)->getServices($service->getId());
switch ($slug) {
case 'vtc-minibus':
case 'autocar':
$devis = $session->get('devis', new Devis());
$form = $this->createForm(DevisType::class, $devis, ['step' => 'step1']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$typeOfTrip = $form->get('typeOfTrip')->getData();
$session->set('typeOfTrip', $typeOfTrip);
$startAddress = $form->get('departureAddress')->getData();
$endAddress = $form->get('arrivalAddress')->getData();
$distanceAndDurationAndRouteNational = $this->distanceCalculator->calculDistance($startAddress, $endAddress, $language);
$distance = $distanceAndDurationAndRouteNational['distance'] ?? null;
$startLocation = $distanceAndDurationAndRouteNational['start_location'] ?? ['lat' => null, 'lng' => null];
$endLocation = $distanceAndDurationAndRouteNational['end_location'] ?? ['lat' => null, 'lng' => null];
if ($typeOfTrip === 'Aller simple') {
$devis->setReturnDate(null);
$devis->setReturnTime(null);
$devis->setDistance($distance);
$devis->setDistancePerTrip(null);
} else if ($typeOfTrip === 'Aller-Retour') {
$devis->setReturnDate(null);
if ($distance) {
$totalDistance = (floatval(str_replace(',', '.', explode(' ', $distance)[0]))) * 2;
$distanceFormatted = number_format($totalDistance, 2, ',', '.') . " km";
$devis->setDistance($distanceFormatted);
$devis->setDistancePerTrip($distance);
}
} else if ($typeOfTrip === 'Séjours') {
if ($distance) {
$totalDistance = (floatval(str_replace(',', '.', explode(' ', $distance)[0]))) * 2;
$distanceFormatted = number_format($totalDistance, 2, ',', '.') . " km";
$devis->setDistance($distanceFormatted);
$devis->setDistancePerTrip($distance);
}
}
$devis->setStartLatitude($startLocation['lat']);
$devis->setStartLongitude($startLocation['lng']);
$devis->setEndLatitude($endLocation['lat']);
$devis->setEndLongitude($endLocation['lng']);
$devis->setService($service);
$devis->setCreatedAtValue();
$session->set('devis', $devis);
return $this->redirectToRoute('app_client_service_route_description', ['slug' => $slug]);
}
return $this->render('front/service/vtc_autocar.html.twig', [
'devis' => $devis,
'entity' => $service,
'services' => $services,
'form' => $form->createView()
]);
case 'ambulance':
return $this->render('front/service/ambulance.html.twig', [
'entity' => $service,
]);
case 'taxi':
return $this->render('front/service/taxi.html.twig', [
'entity' => $service,
]);
case 'covoiturage':
return $this->render('front/service/covoiturage.html.twig', [
'entity' => $service,
]);
default:
throw new NotFoundHttpException('Type de service invalide.');
}
}
/**
* @Route("/service/{slug}/route-description", name="app_client_service_route_description")
*/
public function serviceOptions(
AccessClientService $accessClientService,
string $slug,
SessionInterface $session,
Request $request,
EntityManagerInterface $entityManager
)
{
$accessClientService->handleAccessControl();
$service = $entityManager->getRepository(Service::class)->findOneBy(['slug' => $slug]);
if (!$service) {
throw new NotFoundHttpException('Le service demandé n\'existe pas.');
}
$allowedForQuote = ['vtc-minibus', 'autocar'];
if (!in_array($slug, $allowedForQuote)) {
return $this->redirectToRoute('app_client_service', ['slug' => $slug]);
}
$devis = $session->get('devis');
if (!$devis) {
return $this->redirectToRoute('app_client_service', ['slug' => $slug]);
}
$session->remove('login_info_slug');
$travelReason = $devis->getDevisTravelReason();
if ($travelReason && !$entityManager->contains($travelReason)) {
$devisTravelReason = $entityManager->getRepository(DevisTravelReason::class)->find($travelReason->getId());
if ($devisTravelReason) {
$devis->setDevisTravelReason($devisTravelReason);
}
}
$luggage = $devis->getDevisLuggage();
if ($luggage && !$entityManager->contains($luggage)) {
$devisLuggage = $entityManager->getRepository(DevisLuggage::class)->find($luggage->getId());
if ($devisLuggage) {
$devis->setDevisLuggage($devisLuggage);
}
}
$budget = $devis->getDevisBudget();
if ($budget && !$entityManager->contains($budget)) {
$devisBudget = $entityManager->getRepository(DevisBudget::class)->find($budget->getId());
if ($devisBudget) {
$devis->setDevisBudget($devisBudget);
}
}
$selectedEquipments = $devis->getDevisEquipment();
$managedEquipments = new ArrayCollection();
foreach ($selectedEquipments as $equipment) {
$existingEquipment = $entityManager->getRepository(DevisEquipment::class)
->findOneBy(['name' => $equipment->getName()]);
if ($existingEquipment) {
$managedEquipments->add($existingEquipment);
}
}
$devis->setDevisEquipment($managedEquipments->toArray());
$form = $this->createForm(DevisType::class, $devis, ['step' => 'step2']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$needVehicleOnSite = $form->get('needVehicleOnSite')->getData();
$session->set('needVehicleOnSite', $needVehicleOnSite);
if ($needVehicleOnSite == "Non") {
$devis->getVehicleDetails()->clear();
}
$addPdfDocument = $form->get('addPdfDocument')->getData();
$session->set('addPdfDocument', $addPdfDocument);
if ($addPdfDocument == "Non") {
$devis->getAttachments()->clear();
}
$attachment = $form->get('attachments')->getData();
foreach ($attachment as $devisAttachment) {
$attachFile = $devisAttachment->getAttachFile();
if ($attachFile instanceof UploadedFile) {
$newFilename = uniqid() . '.' . $attachFile->guessExtension();
$uploadDir = $this->getParameter('kernel.project_dir') . '/public/uploads/files/tmp/';
$attachFile->move($uploadDir, $newFilename);
$fileSizeInBytes = $attachFile->getSize();
$fileSizeInKB = round($fileSizeInBytes / 1024, 2);
$fileSizeInMB = round($fileSizeInKB / 1024, 2);
$sizeForSession = ($fileSizeInMB >= 1) ? $fileSizeInMB . ' MB' : $fileSizeInKB . ' KB';
$devisAttachment->setFileName($newFilename);
$devisAttachment->setSize($sizeForSession);
$devis->addAttachment($devisAttachment);
}
}
$session->set('devis', $devis);
return $this->redirectToRoute('app_client_service_login_info', ['slug' => $slug]);
}
return $this->render('front/service/step2/route_description.html.twig', [
'service' => $service,
'devis' => $devis,
'form' => $form->createView()
]);
}
/**
* @Route("/service/{slug}/login-info", name="app_client_service_login_info")
*/
public function loginInfo(
AccessClientService $accessClientService,
AddressInfoService $addressInfoService,
string $slug,
SessionInterface $session,
Request $request,
EntityManagerInterface $entityManager,
Security $security,
AuthenticationUtils $authenticationUtils,
UserPasswordEncoderInterface $passwordEncoder
) {
$accessClientService->handleAccessControl();
$service = $entityManager->getRepository(Service::class)->findOneBy(['slug' => $slug]);
if (!$service) {
throw new NotFoundHttpException('Le service demandé n\'existe pas.');
}
$allowedForQuote = ['vtc-minibus', 'autocar'];
if (!in_array($slug, $allowedForQuote)) {
return $this->redirectToRoute('app_client_service', ['slug' => $slug]);
}
$devis = $session->get('devis');
if (!$devis) {
return $this->redirectToRoute('app_client_service', ['slug' => $slug]);
}
if ($security->isGranted('IS_AUTHENTICATED_FULLY')) {
if ($session->has('login_info_slug')) {
$session->remove('login_info_slug');
}
if ($session->has('register_info_slug')) {
$session->remove('register_info_slug');
}
$user = $this->getUser();
$client = $user->getClient();
if (!$client) {
throw new NotFoundHttpException('Aucun client trouvé pour cet utilisateur ' . $user->getFirstname());
}
$form = $this->createForm(ClientDevisType::class, $client);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$civility = $form->get('user')->get('civility')->getData();
$lastname = $form->get('user')->get('lastname')->getData();
$firstname = $form->get('user')->get('firstname')->getData();
$address = $form->get('address')->getData();
$posteZip = $form->get('postalCode')->getData();
$ville = $form->get('city')->getData();
if ($civility === 'Monsieur' || $civility === 'Madame') {
$client->setEntrepriseName(null);
$client->setSiret(null);
}
$user->setLastname($lastname);
$user->setFirstname($firstname);
$user->setUpdatedAtValue();
$user->preUpdate();
$addressInfo = $addressInfoService->getAddressInfo($address);
if ($addressInfo !== null) {
$postalCode = $addressInfo['postal_code'];
$city = $addressInfo['city'];
$longitude = $addressInfo['longitude'];
$latitude = $addressInfo['latitude'];
} else {
$postalCode = null;
$city = null;
$longitude = null;
$latitude = null;
}
if ($postalCode !== null && $posteZip !== $postalCode) {
$client->setPostalCode($postalCode);
}
if ($city !== null && $ville !== $city) {
$client->setCity($city);
}
if ($longitude !== null) {
$client->setLongitude($longitude);
}
if ($latitude !== null) {
$client->setLatitude($latitude);
}
$entityManager->persist($user);
$entityManager->persist($client);
$entityManager->flush();
return $this->redirectToRoute('app_client_service_summary', ['slug' => $slug]);
}
return $this->render('front/service/step3/login_info.html.twig', [
'service' => $service,
'devis' => $devis,
'slug' => $slug,
'client' => $client,
'user' => $user,
'form' => $form->createView()
]);
}
else {
if (!$session->has('login_info_slug')) {
$session->set('login_info_slug', $slug);
}
if (!$session->has('register_info_slug')) {
$session->set('register_info_slug', $slug);
}
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
$user = new User();
$client = new Client();
$form = $this->createForm(ClientType::class, $client, [
'action' => $this->generateUrl('app_front_register')
]);
$form->handleRequest($request);
return $this->render('front/service/step3/login_info.html.twig', [
'service' => $service,
'devis' => $devis,
'last_username' => $lastUsername,
'error' => $error,
'slug' => $slug,
'form' => $form->createView()
]);
}
}
/**
* @Route("/service/{slug}/summary", name="app_client_service_summary")
*/
public function summary(
AccessClientService $accessClientService,
string $slug,
Request $request,
SessionInterface $session,
EntityManagerInterface $entityManager,
Security $security
) {
$accessClientService->handleAccessControl();
$service = $entityManager->getRepository(Service::class)->findOneBy(['slug' => $slug]);
if (!$service) {
throw new NotFoundHttpException('Le service demandé n\'existe pas.');
}
$allowedForQuote = ['vtc-minibus', 'autocar'];
if (!in_array($slug, $allowedForQuote)) {
return $this->redirectToRoute('app_client_service', ['slug' => $slug]);
}
$devis = $session->get('devis');
if (!$devis) {
return $this->redirectToRoute('app_client_service', ['slug' => $slug]);
}
$devis->setService($service);
$travelReason = $devis->getDevisTravelReason();
if ($travelReason && !$entityManager->contains($travelReason)) {
$devisTravelReason = $entityManager->getRepository(DevisTravelReason::class)->find($travelReason->getId());
if ($devisTravelReason) {
$devis->setDevisTravelReason($devisTravelReason);
}
}
$luggage = $devis->getDevisLuggage();
if ($luggage && !$entityManager->contains($luggage)) {
$devisLuggage = $entityManager->getRepository(DevisLuggage::class)->find($luggage->getId());
if ($devisLuggage) {
$devis->setDevisLuggage($devisLuggage);
}
}
$budget = $devis->getDevisBudget();
if ($budget && !$entityManager->contains($budget)) {
$devisBudget = $entityManager->getRepository(DevisBudget::class)->find($budget->getId());
if ($devisBudget) {
$devis->setDevisBudget($devisBudget);
}
}
$form = $this->createForm(DevisType::class, $devis, ['step' => 'step3']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if (
!$devis->isMiseEnAvance() &&
!$devis->isRemonteEnTeteDeListe() &&
!$devis->isDemandeUrgente()
) {
$this->addFlash('danger', 'Avertissement ! Veuillez sélectionner au moins une option.');
return $this->redirectToRoute('app_client_service_summary', ['slug' => $slug]);
}
$totalCost = 0;
if ($devis->isMiseEnAvance()) {
$totalCost += 6;
}
if ($devis->isRemonteEnTeteDeListe()) {
$totalCost += 8;
}
if ($devis->isDemandeUrgente()) {
$totalCost += 3;
}
$user = $security->getUser();
if ($user->getCreditBalance() >= $totalCost) {
$user->debitCredits($totalCost);
$devisAttachment = $devis->getAttachments();
if ($devisAttachment) {
foreach ($devisAttachment as $attachment) {
$finalPath = $this->getParameter('kernel.project_dir') . '/public/uploads/files/devis/attachments/';
$sourcePath = $this->getParameter('kernel.project_dir') . '/public/uploads/files/tmp/' . $attachment->getFileName();
if (!file_exists($finalPath . $attachment->getFileName())) {
if (file_exists($sourcePath)) {
rename($sourcePath, $finalPath . $attachment->getFileName());
} else {
$this->addFlash('danger', 'Veuillez rajouter le fichier, il est manquant ou ...');
return $this->redirectToRoute('app_client_service_summary', ['slug' => $slug]);
}
}
$attachment->setDevis($devis);
$entityManager->persist($attachment);
}
}
foreach ($devis->getDevisEquipment() as $equipment) {
$existingEquipment = $entityManager->getRepository(DevisEquipment::class)->findOneBy(['name' => $equipment->getName()]);
if ($existingEquipment) {
$devis->removeDevisEquipment($equipment);
$devis->addDevisEquipment($existingEquipment);
}
}
$devis->setUser($user);
$entityManager->persist($devis);
$entityManager->flush();
$session->remove('typeOfTrip');
$session->remove('needVehicleOnSite');
$session->remove('addPdfDocument');
$session->remove('uploaded_files');
$session->remove('devis');
$this->addFlash('success', 'Succès ! Votre demande de devis a été validée.');
return $this->redirectToRoute('app_client_devis_pending');
} else {
$this->addFlash('danger', 'Avertissement ! Vous n\'avez pas assez de crédit, rechargez votre portefeuille.');
return $this->redirectToRoute('app_client_service_summary', ['slug' => $slug]);
}
}
return $this->render('front/service/step4/recapitulatif.html.twig', [
'service' => $service,
'devis' => $devis,
'form' => $form->createView(),
'stripe_public_key' => $this->getParameter('stripe_public_key')
]);
}
}