src/Controller/Frontend/DefaultController.php line 63

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the VPAutoUserBundle package.
  4.  *
  5.  * (c) CNSX <http://www.cnsx.net/>
  6.  *
  7.  */
  8. namespace App\Controller\Frontend;
  9. use App\Api\RMS\SaleEventDataPersister;
  10. use App\Controller\Controller;
  11. use App\Entity\ExternalSale;
  12. use App\Entity\News;
  13. use App\Entity\Sale;
  14. use App\Entity\SaleEvent;
  15. use App\Entity\User;
  16. use App\Entity\Vehicle;
  17. use App\Form\Type\Frontend\CgvValidationType;
  18. use App\Form\Type\Frontend\NewsletterType;
  19. use App\Form\Type\Frontend\ProspectingProType;
  20. use App\Form\Type\Frontend\VehicleFreeSearchType;
  21. use App\Parameter\Provider;
  22. use App\Parameter\ProviderInterface;
  23. use App\Payment\Dto\Payment;
  24. use App\Payment\PaymentFunnel;
  25. use App\Repository\AuctionRepository;
  26. use App\Repository\BannerRepository;
  27. use App\Repository\NewsRepository;
  28. use App\Repository\SaleHighlightRepository;
  29. use App\Repository\SaleRepository;
  30. use App\Repository\UserRepository;
  31. use App\Repository\VehicleRepository;
  32. use App\Salesforce\Api\ClientInterface;
  33. use App\Salesforce\Utils\Constants;
  34. use App\Twig\Extension\CountryExtension;
  35. use App\Twig\Extension\OfferExtension;
  36. use Doctrine\ORM\EntityManagerInterface;
  37. use Symfony\Component\HttpFoundation\JsonResponse;
  38. use Symfony\Component\HttpFoundation\Request;
  39. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  40. use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
  41. class DefaultController extends Controller
  42. {
  43.     public function __construct(
  44.         private readonly SaleRepository $saleRepository,
  45.         private readonly NewsRepository $newsRepository,
  46.         private readonly BannerRepository $bannerRepository,
  47.         private readonly UserRepository $userRepository,
  48.         private readonly AuctionRepository $auctionRepository,
  49.         private readonly VehicleRepository $vehicleRepository,
  50.         private readonly SaleHighlightRepository $saleHighlightRepository,
  51.         private readonly ClientInterface $client,
  52.         private readonly SessionInterface $session,
  53.         private readonly OfferExtension $offerExtension,
  54.         private readonly ProviderInterface $provider,
  55.         private readonly string $country)
  56.     {
  57.     }
  58.     public function indexAction(Request $requestProvider $provider)
  59.     {
  60.         $user $this->getUser();
  61.         $nextSale $this->saleRepository->findVeryNextSale();
  62.         $nextLiveFirst $this->saleRepository->findCurrentOrNextLiveCompatible();
  63.         $nextLives $this->saleRepository->findLiveCompatibleByDate($nextLiveFirst $nextLiveFirst->getStartDate() : new \DateTime());
  64.         $highlightEvent null !== $nextLiveFirst $nextLiveFirst->getEvents()->first() : null;
  65.         $news $this->newsRepository->findByType(News::TYPE_B2C);
  66.         $banners $this->bannerRepository->findBanners($this->getParameter('vpauto_particular'), $request->getLocale());
  67.         $vehiclesSelection $this->vehicleRepository->getVehiclesForAuctioneerSelection((int) $provider->getParameterValue('home.auctioneer.number_selection'));
  68.         $this->session->set('dimension''private');
  69.         if (null === $nextSale) {
  70.             return $this->render('Frontend/index_no_sales.html.twig', [
  71.                 'news' => $news,
  72.             ]);
  73.         }
  74.         $nbVehiclesSales $this->saleRepository->countVehiclesForActiveByUserAndCustomer($user);
  75.         $nextSales $this->getCurrentSales($this->country);
  76.         return $this->render('/Frontend/index.html.twig', [
  77.             'nextSale' => $nextSale,
  78.             'nextLiveFirst' => $nextLiveFirst,
  79.             'nextLives' => $nextLives,
  80.             'highlightEvent' => $highlightEvent,
  81.             'nbVehiclesSales' => $nbVehiclesSales,
  82.             'vehiclesSelection' => $vehiclesSelection,
  83.             'nextSales' => $nextSales,
  84.             'news' => $news,
  85.             'banners' => $banners,
  86.             'search_form' => $this->createForm(VehicleFreeSearchType::class, null, ['user' => $user])->createView(),
  87.             'type' => 'private',
  88.         ]);
  89.     }
  90.     public function indexProAction(Request $request)
  91.     {
  92.         $user $this->getUser();
  93.         $this->session->set('dimension''pro');
  94.         $banners $this->bannerRepository->findBanners($this->getParameter('vpauto_professional'), $request->getLocale());
  95.         $currentSales $this->getCurrentSalesForPro($this->country);
  96.         $datesForExternalSales $this->getDatesForExternalSales($currentSales);
  97.         $nextLive $this->saleRepository->findCurrentOrNextLiveCompatible();
  98.         $highlightEvent null !== $nextLive $nextLive->getEvents()->first() : null;
  99.         return $this->render('/Frontend/index.html.twig', [
  100.             'news' => $this->newsRepository->findByType(News::TYPE_B2B),
  101.             'banners' => $banners,
  102.             'currentSales' => $currentSales,
  103.             'afterSales' => $this->saleRepository->findAllInAftersale(),
  104.             'search_form' => $this->createForm(VehicleFreeSearchType::class, null, ['user' => $user])->createView(),
  105.             'type' => 'pro',
  106.             'datesForExternalSales' => $datesForExternalSales,
  107.             'nextLive' => $nextLive,
  108.             'highlightEvent' => $highlightEvent,
  109.         ]);
  110.     }
  111.     public function refreshSalesAction(Request $request)
  112.     {
  113.         if (!$request->isXmlHttpRequest()) {
  114.             throw new UnauthorizedHttpException('Unauthorized request');
  115.         }
  116.         $currentSales $this->getCurrentSalesForPro($this->country);
  117.         $datesForExternalSales $this->getDatesForExternalSales($currentSales);
  118.         return new JsonResponse($this->renderView('/Frontend/home/_sales_list.html.twig', [
  119.             'currentSales' => $currentSales,
  120.             'afterSales' => $this->saleRepository->findAllInAftersale(),
  121.             'datesForExternalSales' => $datesForExternalSales,
  122.             'nextLive' => $this->saleRepository->findCurrentOrNextLiveCompatible(),
  123.         ]));
  124.     }
  125.     public function liveVisitorAction(Request $requestProvider $providerEntityManagerInterface $em)
  126.     {
  127.         $isDisabled = (int) $provider->getParameterValue('live.disable_visitors');
  128.         if ($isDisabled) {
  129.             return $this->render('/Frontend/live_visitor_disabled.html.twig');
  130.         }
  131.         if (null !== $sale $this->saleRepository->findCurrentLiveCompatible()) {
  132.             $sale->addOneLiveVisitor();
  133.             $em->flush();
  134.         }
  135.         $language $request->getLocale();
  136.         $user $this->userRepository->findOneByEmail($this->getParameter('vpauto.live.test_user').'@vpauto.'.$language);
  137.         $url $this->createLiveUrlForUser($user$this->provider$em);
  138.         return $this->redirect($url);
  139.     }
  140.     public function livePaymentAction(PaymentFunnel $paymentFunnelEntityManagerInterface $em)
  141.     {
  142.         $user $this->getUser();
  143.         /** @var Sale $sale */
  144.         $sale $this->saleRepository->findCurrentOrNextLiveCompatible();
  145.         if ($this->checkUserAccessToSale($user$sale$em)) {
  146.             $url $this->createLiveUrlForUser($user$this->provider$em);
  147.             return $this->redirect($url);
  148.         }
  149.         $payment = new Payment(Payment::OPERATION_LIVE_ACCESS);
  150.         $payment->setSale($sale);
  151.         $payment->setFinishUrl($this->generateUrl('vpauto_frontend_live', [
  152.             'saleId' => $sale->getId(),
  153.         ]));
  154.         $payment->setUser($this->getUser());
  155.         return $paymentFunnel->startAndRedirect($payment);
  156.     }
  157.     public function newsletterAction(Request $request)
  158.     {
  159.         $form $this->createForm(NewsletterType::class);
  160.         $form->handleRequest($request);
  161.         if ($form->isSubmitted() && $form->isValid()) {
  162.             $newsletter $form->getData();
  163.             if (
  164.                 null !== $newsletter->getEmail()
  165.                 && null !== $newsletter->getLastName()
  166.                 && null !== $newsletter->getFirstName()
  167.             ) {
  168.                 if ('proAuto' === $form->get('type')->getData()) {
  169.                     return $this->render('/Frontend/landing/newsletter-registered_pro.html.twig');
  170.                 }
  171.                 $sObject = [
  172.                     'ExternalId__c' => $newsletter->getEmail(),
  173.                     'LastName' => $newsletter->getLastName(),
  174.                     'FirstName' => $newsletter->getFirstName(),
  175.                     'PersonMailingPostalCode' => $newsletter->getZipCode(),
  176.                     'PersonMailingCity' => $newsletter->getCity(),
  177.                     'PersonMobilePhone' => $newsletter->getMobile(),
  178.                     'Inscription_Newsletter__c' => true,
  179.                     'Salle_de_vente_Newsletter__c' => $newsletter->getRoom() ? implode(';'$newsletter->getRoom()) : 'Toutes',
  180.                     'SMS_Newsletter__c' => null !== $newsletter->getMobile() ? $newsletter->getSms() : false,
  181.                     'RecordTypeId' => Constants::ACCOUNT_PERSON,
  182.                 ];
  183.                 if ('proOther' === $form->get('type')->getData()) {
  184.                     $sObject['Description'] = 'Professionnel d\'un autre secteur d\'activité';
  185.                 }
  186.                 $sfClient $this->client->initiate();
  187.                 if (false !== $exists $sfClient->exists('Lead', ['Email' => $newsletter->getEmail()])) {
  188.                     $convRes $sfClient->convert($exists['id'], $newsletter->getId());
  189.                     $sObject['Id'] = $convRes['accId'];
  190.                     $sfClient->upsert('Id', (object) $sObject'Account');
  191.                 } else {
  192.                     $sfClient->upsert('ExternalId__c', (object) $sObject'Account');
  193.                 }
  194.                 return $this->render('/Frontend/landing/newsletter-registered.html.twig');
  195.             }
  196.             $this->session->getFlashbag()->add('error''Veuillez remplir les champs obligatoires.');
  197.         }
  198.         return $this->render('/Frontend/landing/newsletter-registration.html.twig', [
  199.             'form' => $form->createView(),
  200.         ]);
  201.     }
  202.     public function assistanceContactAction(Request $request)
  203.     {
  204.         $user $this->getCurrentUserOr403();
  205.         return $this->render('/Frontend/pro/assistance_contact.html.twig', [
  206.             'salesman' => $user->getSalesman(),
  207.         ]);
  208.     }
  209.     public function cgvValidationAction(Request $requestEntityManagerInterface $em)
  210.     {
  211.         $user $this->getCurrentUserOr403();
  212.         $form $this->createForm(CgvValidationType::class);
  213.         $form->handleRequest($request);
  214.         if ($form->isSubmitted() && $form->isValid()) {
  215.             if (null !== $user) {
  216.                 $user->setCgvValidatedAt(new \DateTime());
  217.                 $em->flush();
  218.             }
  219.             return $this->redirect($this->generateUrl('homepage_pro'));
  220.         }
  221.         return $this->render('/Frontend/cgv/validation.html.twig', [
  222.             'form' => $form->createView(),
  223.         ]);
  224.     }
  225.     public function prospectingProAction(Request $request)
  226.     {
  227.         $form $this->createForm(ProspectingProType::class);
  228.         $form->handleRequest($request);
  229.         if ($form->isSubmitted() && $form->isValid()) {
  230.             $sObject = (object) [
  231.                 'LastName' => $form['lastName']->getData(),
  232.                 'MobilePhone' => $form['mobile']->getData(),
  233.                 'Company' => $form['company']->getData(),
  234.                 'Email' => $form['email']->getData(),
  235.                 'LeadSource' => 'Prospection campagne Salesfactory',
  236.             ];
  237.             $sfClient $this->client->initiate();
  238.             $data $sfClient->upsert('Email'$sObject'Lead');
  239.             if (true !== $data[0]->success) {
  240.                 $this->session->getFlashbag()->add('error''Une erreur est survenu, veuillez vérifier que les champs remplies sont correctement renseignés.');
  241.             } else {
  242.                 $this->session->getFlashbag()->add('success''Votre inscription a bien été prise en compte.');
  243.             }
  244.         }
  245.         return $this->render('/Frontend/landing/prospecting-pro.html.twig', [
  246.             'form' => $form->createView(),
  247.         ]);
  248.     }
  249.     private function formatTimerTargetDate($targetDate)
  250.     {
  251.         if ('DateTime' === $targetDate::class) {
  252.             return $targetDate->format('m/d/Y H:i:s');
  253.         }
  254.         return date('m/d/Y H:i:s'$targetDate);
  255.     }
  256.     private function getDatesForExternalSales(array $currentSales): array
  257.     {
  258.         $datesForExternalSales = [];
  259.         foreach ($currentSales as $currentSale) {
  260.             $sale $currentSale['sale'];
  261.             if ($sale instanceof ExternalSale && SaleEventDataPersister::PROVIDER_NAME === $sale->getProvider()) {
  262.                 $dates $this->auctionRepository->findMinAndMaxClosedAtForSale($sale);
  263.                 $dates array_shift($dates);
  264.                 if ($dates['max_closedAt'] != $dates['min_closedAt']) {
  265.                     $datesForExternalSales[$sale->getId()] = ['max_closedAt' => new \DateTime($dates['max_closedAt']), 'min_closedAt' => new \DateTime($dates['min_closedAt'])];
  266.                 }
  267.             }
  268.         }
  269.         return $datesForExternalSales;
  270.     }
  271.     private function getCurrentSales(string $country)
  272.     {
  273.         /** @var User|null $user */
  274.         $user $this->getUser();
  275.         $nextSales $currentSales = [];
  276.         $countries = [
  277.             'fr' => 'France',
  278.             'be' => 'Belgique',
  279.             'pt' => 'Portugal',
  280.             'es' => 'Espagne',
  281.         ];
  282.         if (in_array($country, [CountryExtension::COUNTRY_BELGIUMCountryExtension::COUNTRY_PORTUGALCountryExtension::COUNTRY_SPAIN])) {
  283.             foreach ($countries as $key => $countryName) {
  284.                 $nextSales[$key] = $this->saleRepository->findActiveByUserAndPhysicalAndCountry($user$countryName5);
  285.                 $currentSales[$key] = $this->getCurrentSalesData($nextSales[$key]);
  286.             }
  287.             return $currentSales;
  288.         }
  289.         $nextSales $this->saleRepository->findActiveByUserAndCustomer($user);
  290.         return $this->getCurrentSalesData($nextSales);
  291.     }
  292.     private function getCurrentSalesData(array $sales)
  293.     {
  294.         $currentSalesData = [];
  295.         foreach ($sales as $sale) {
  296.             $currentSaleData = [
  297.                 'sale' => $sale,
  298.                 'vehicles_for_carousel' => $this->vehicleRepository->getPicturesLotPhareByLiveSaleQuery($sale),
  299.                 'count_active_vehicles' => $this->vehicleRepository->countAllValidBySale($sale),
  300.                 'highlight' => $this->saleHighlightRepository->findOneRandomBySale($sale),
  301.                 'count_vehicles_by_event' => $this->getCountVehiclesByEvent($sale),
  302.             ];
  303.             $currentSalesData[] = $currentSaleData;
  304.         }
  305.         return $currentSalesData;
  306.     }
  307.     private function getCountVehiclesByEvent($sale): array
  308.     {
  309.         $countVehiclesByEvent = [];
  310.         foreach ($sale->getEvents() as $event) {
  311.             $countVehiclesByEvent[$event->getId()] = $this->vehicleRepository->countAllValidBySale($sale$event);
  312.         }
  313.         return $countVehiclesByEvent;
  314.     }
  315.     private function getCurrentSalesForPro(string $country)
  316.     {
  317.         /** @var User|null $user */
  318.         $user $this->getUser();
  319.         $allCurrent $this->saleRepository->findAllCurrent($country);
  320.         $currentSales = [];
  321.         /** @var Sale $currentSale */
  322.         foreach ($allCurrent as $currentSale) {
  323.             $highlightVehicles $this->vehicleRepository->findHighlightBySale($currentSale);
  324.             $userHighestOffers = [];
  325.             /** @var Vehicle $highlightVehicle */
  326.             foreach ($highlightVehicles as $highlightVehicle) {
  327.                 $userHighestOffers[$highlightVehicle->getId()] = $this->offerExtension->getUserHighestOffer($user$highlightVehicle);
  328.             }
  329.             $countAllValidVehicles $this->vehicleRepository->countAllValidBySale($currentSale);
  330.             $currentSaleData = [
  331.                 'sale' => $currentSale,
  332.                 'count_active_vehicles' => $countAllValidVehicles,
  333.                 'count_vehicles' => $countAllValidVehicles,
  334.                 'highlight_vehicles' => [
  335.                     'vehicles' => $highlightVehicles,
  336.                     'highest_offers' => $userHighestOffers,
  337.                 ],
  338.             ];
  339.             if (Sale::TYPE_PHYSICAL === $currentSale->getType()) {
  340.                 $countVehiclesByEvent = [];
  341.                 /** @var SaleEvent $event */
  342.                 foreach ($currentSale->getEvents() as $event) {
  343.                     $countVehiclesByEvent[$event->getId()] = $this->vehicleRepository->countAllValidBySale($currentSale$event);
  344.                 }
  345.                 $currentSaleData['count_vehicles_by_event'] = $countVehiclesByEvent;
  346.             }
  347.             $currentSales[] = $currentSaleData;
  348.         }
  349.         return $currentSales;
  350.     }
  351. }