src/Controller/ShopApiController.php line 44

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controller;
  4. use App\Entity\Order\OrderItem;
  5. use App\Entity\Product\ProductVariant;
  6. use App\Repository\TaxonRepository;
  7. use Dflydev\DotAccessData\Data;
  8. use GuzzleHttp\Client;
  9. use Swift_Mailer;
  10. use Sylius\Bundle\CoreBundle\Mailer\Emails;
  11. use Sylius\Bundle\ProductBundle\Doctrine\ORM\ProductVariantRepository;
  12. use Sylius\Component\Mailer\Sender\SenderInterface;
  13. use Sylius\Component\Order\Context\CartContextInterface;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\Filesystem\Filesystem;
  16. use Symfony\Component\HttpFoundation\JsonResponse;
  17. use Symfony\Component\HttpFoundation\Request as HttpRequest;
  18. use GuzzleHttp\Psr7\Request;
  19. use Aws\Credentials\Credentials;
  20. use Aws\Signature\SignatureV4;
  21. use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface;
  22. use Symfony\Component\HttpClient\HttpClient;
  23. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  24. use Symfony\Component\HttpKernel\KernelInterface;
  25. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  26. class ShopApiController extends AbstractController
  27. {
  28.     /** @var TaxonRepository */
  29.     private $taxonRepository;
  30.     private $router;
  31.     public function __construct(TaxonRepositoryInterface $taxonRepositoryUrlGeneratorInterface $router)
  32.     {
  33.         $this->taxonRepository $taxonRepository;
  34.         $this->router $router;
  35.     }
  36.     public function getDealersAction(KernelInterface $kernel){
  37.         $filesystem = new Filesystem();
  38.         $serviceCenterFile $kernel->getProjectDir().'/private/service_center/list.json';
  39.         if (!file_exists($serviceCenterFile) || time()-filemtime($serviceCenterFile) > 3600) {
  40.             $url getenv('PAYMENT_SERVICE_URL').'/get-dealers/'.$_ENV['BRAND'];
  41.             [$content$code] = $this->getApiServiceResponse($url'GET');
  42.             if( $code == 200 )
  43.                 $filesystem->dumpFile($serviceCenterFilejson_encode($content));
  44.             return $this->json($content$code);
  45.         }
  46.         else{
  47.             $response $this->file($serviceCenterFile);
  48.             $response->headers->set('Content-Type''application/json');
  49.             return $response;
  50.         }
  51.     }
  52.     public function getDealerTerms($idKernelInterface $kernel){
  53.         $filesystem = new Filesystem();
  54.         $priceDir $kernel->getProjectDir().'/private/service_center/terms/';
  55.         foreach(['docx','doc','pdf'] as $ext){
  56.             $terms_file $priceDir.$id.'.'.$ext;
  57.             if( $filesystem->exists($terms_file) )
  58.                 return $this->file($terms_file);
  59.         }
  60.         throw new NotFoundHttpException();
  61.     }
  62.     public function sendOutOfStockAlert(HttpRequest $requestKernelInterface $kernel){
  63.         $data json_decode($request->getContent(), true);
  64.         $httpClient HttpClient::create();
  65.         $url getenv('PAYMENT_SERVICE_URL') . '/request-on-demand-product';
  66.         try {
  67.             $response $httpClient->request('POST'$url, [
  68.                 'json' => $data,
  69.             ]);
  70.     
  71.             $statusCode $response->getStatusCode();
  72.     
  73.             if ($statusCode === 200 || $statusCode === 201) {
  74.                 return new JsonResponse(['message' => 'Alert successfully sent.'], $statusCode);
  75.             }
  76.     
  77.             return new JsonResponse([
  78.                 'error' => 'Failed to send alert.',
  79.                 'details' => $response->getContent(),
  80.             ], $statusCode);
  81.         } catch (\Exception $e) {
  82.             return new JsonResponse([
  83.                 'error' => 'An error occurred while sending the alert.',
  84.                 'details' => $e->getMessage(),
  85.             ], 500);
  86.         }
  87.     }
  88.     public function getVin($vinTaxonRepository $taxonRepository) {
  89.         $url getenv('PAYMENT_SERVICE_URL') . '/vehicle-infos-by-vin/' $vin;
  90.     
  91.         [$content$statusCode] = $this->getApiServiceResponse($url'GET');
  92.     
  93.         $response is_string($content) ? json_decode($contenttrue) : $content;
  94.     
  95.         if (isset($response['REVE']['CODE_ERREUR'])) {
  96.             return $this->json([
  97.                 'error' => true,
  98.                 'code' => $response['REVE']['CODE_ERREUR'],
  99.                 'message' => $response['REVE']['MESSAGE_ERREUR']
  100.             ], $statusCode);
  101.         }
  102.     
  103.         $vehicleData $response['REVE']['VEHICULE'];
  104.         $modelYear $vehicleData['CODE_ANNEE_MODELE'];
  105.         $modelLabel $vehicleData['LIBELLE_CODE_MODELE'];
  106.     
  107.         $formattedModelLabel preg_replace('/[^a-zA-Z0-9]/''_'strtolower($modelLabel));
  108.     
  109.         $matchedTaxon $taxonRepository->findOneByCode($formattedModelLabel);
  110.     
  111.         if (!$matchedTaxon) {
  112.             $modelParts explode(' 'strtolower($modelLabel));
  113.             foreach ($modelParts as $part) {
  114.                 $matchedTaxon $taxonRepository->findOneByCode($part);
  115.                 if ($matchedTaxon) {
  116.                     break;
  117.                 }
  118.             }
  119.         }
  120.         $modelName $matchedTaxon;
  121.     
  122.         if ($matchedTaxon) {
  123.             $potentialTaxons $taxonRepository->createQueryBuilder('t')
  124.                 ->where('t.code LIKE :prefix')
  125.                 ->setParameter('prefix'$matchedTaxon '%')
  126.                 ->getQuery()
  127.                 ->getResult();
  128.     
  129.             // Attempt to match the taxon based on the model year range
  130.             foreach ($potentialTaxons as $taxon) {
  131.                 if (preg_match('/_(\d{4})(?:_(\d{4}))?$/'$taxon->getCode(), $matches)) {
  132.                     $startYear = (int)$matches[1];
  133.                     $endYear = isset($matches[2]) ? (int)$matches[2] : null;
  134.     
  135.                     if (($endYear === null && $modelYear >= $startYear) || 
  136.                         ($endYear !== null && $modelYear >= $startYear && $modelYear <= $endYear)) {
  137.                         $matchedTaxon $taxon;
  138.                         break;
  139.                     }
  140.                 }
  141.             }
  142.         }
  143.     
  144.         if ($matchedTaxon) {
  145.             $formattedResponse str_replace('_''-'$matchedTaxon->getCode());
  146.     
  147.             $redirectUrl $this->router->generate('sylius_shop_collection', ['slug' => $formattedResponse]);
  148.     
  149.             return $this->json([
  150.                 'model' => $modelName ' (' $modelYear ')',
  151.                 'path' => $redirectUrl
  152.             ], $statusCode);
  153.         } else {
  154.             return $this->json([
  155.                 'error' => true,
  156.                 'code' => 'MODEL_NOT_FOUND',
  157.                 'message' => "Aucun modèle correspondant trouvé pour l'année spécifiée"
  158.             ], $statusCode);
  159.         }
  160.     }
  161.     
  162.     
  163.     public function getDealerAction($service_center_idKernelInterface $kernel){
  164.         $filesystem = new Filesystem();
  165.         $priceDir $kernel->getProjectDir().'/private/service_center/prices/';
  166.         $prices_file $priceDir.$service_center_id.'.json';
  167.         $prices = [];   
  168.         if( $filesystem->exists($prices_file) ){
  169.             $data json_decode(file_get_contents($prices_file), true);
  170.             foreach ($data as $sku=>$_data) {
  171.                 $practicedPrice = isset($_data['practicedPriceTTC']) && !empty($_data['practicedPriceTTC']) ? $_data['practicedPriceTTC']*100 null;
  172.                 $vendorPrice = isset($_data['vendorPriceTTC']) && !empty($_data['vendorPriceTTC']) ? $_data['vendorPriceTTC']*100 null;
  173.               
  174.                 $prices[$sku] = $practicedPrice !== null $practicedPrice $vendorPrice
  175.             }
  176.         }
  177.         $termsDir $kernel->getProjectDir().'/private/service_center/terms/';
  178.         $term false;
  179.         foreach(['docx','doc','pdf'] as $ext){
  180.             $terms_file $termsDir.$service_center_id.'.'.$ext;
  181.             if( $filesystem->exists($terms_file) )
  182.                 $term true;
  183.         }
  184.         $has_payment false;
  185.         $url getenv('PAYMENT_SERVICE_URL').'/has-payment/'.$service_center_id;
  186.         [$content$code] = $this->getApiServiceResponse($url'GET');
  187.         if($code==200)
  188.             $has_payment $content;
  189.         return $this->json(['prices'=>$prices'has_term'=>$term'has_payment'=>$has_payment]);
  190.     }
  191.     private function getApiServiceResponse($url$method$data=[]){
  192.         $access_key getenv('AWS_ACCESS_KEY');
  193.         $secret_key getenv('AWS_SECRET_KEY');
  194.         $region getenv('AWS_REGION');
  195.         $credentials = new Credentials($access_key$secret_key);
  196.         $client = new Client();
  197.         $request = new Request($method$url, ['content-type' => 'application/json'], json_encode($data));
  198.         $s4 = new SignatureV4("execute-api"$region);
  199.         $signedRequest $s4->signRequest($request$credentials);
  200.         try {
  201.             $response $client->send($signedRequest);
  202.             $content json_decode($response->getBody()->getContents(), true);
  203.             $code 200;
  204.         }
  205.         catch (\Throwable $t) {
  206.             $content $t->getMessage();
  207.             $code 500;
  208.         }
  209.         return [$content$code];
  210.     }
  211.     /**
  212.      * @param HttpRequest $request
  213.      * @param KernelInterface $kernel
  214.      * @param CartContextInterface $cartContext
  215.      * @param Swift_Mailer $mailer
  216.      * @param ProductVariantRepository $productVariantRepository
  217.      * @param SenderInterface $sender
  218.      * @return JsonResponse
  219.      */
  220.     public function createLeadAction(HttpRequest $requestKernelInterface $kernelCartContextInterface $cartContextSwift_Mailer $mailerProductVariantRepository $productVariantRepository){
  221.         $data = [
  222.             'first_name' => $request->get('first_name'),
  223.             'last_name' => $request->get('last_name'),
  224.             'phone_number' => $request->get('phone_number'),
  225.             'title' => $request->get('title','mr'),
  226.             'accessories_details' => $request->get('accessories_details',[]),
  227.             'email' => $request->get('email'),
  228.             'dealer' => $request->get('dealer')
  229.         ];
  230.         $brand $request->get('brand');
  231.         $brand $_ENV['BRAND'];
  232.         $cart $cartContext->getCart();
  233.         $data['order'] = $cart;
  234.         if( $data['dealer']??false ){
  235.             $serviceCenterFile $kernel->getProjectDir().'/private/service_center/list.json';
  236.             if( file_exists($serviceCenterFile) ){
  237.                 $partners json_decode(file_get_contents($serviceCenterFile), true);
  238.                 foreach ($partners as $partner){
  239.                     if( $partner['kvps'] == $data['dealer'] ){
  240.                         $data['partner'] = $partner;
  241.                         break;
  242.                     }
  243.                 }
  244.             }
  245.         }
  246.         try{
  247.             $translations = new Data(json_decode(file_get_contents(__DIR__.'/../../translations/'.$brand.'.json'), true));
  248.             $message = (new \Swift_Message())
  249.                 ->setSubject($translations->get('email.title'))
  250.                 ->setFrom([$translations->get('email.from') => $translations->get('email.brand')])
  251.                 ->setTo($data['email']);
  252.             $message->setBody($this->renderView('@SyliusShop/Email/orderSaved.html.twig'$data), 'text/html');
  253.             return $this->json($mailer->send($message));
  254.         }
  255.         catch (\Throwable $t){
  256.             return $this->json(['message'=>$t->getMessage()], 500);
  257.         }
  258.     }
  259. }