src/Controller/CartController.php line 692

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Delivery;
  4. use App\Entity\Vinyl;
  5. use App\Repository\PromoteRepository;
  6. use App\Services\TaxService;
  7. use Psr\Log\LoggerInterface;
  8. use Stripe\Stripe;
  9. use App\Entity\Uid;
  10. use App\Entity\Order;
  11. use Twig\Environment;
  12. use App\Entity\Detail;
  13. use DateTimeImmutable;
  14. use App\Entity\Invoice;
  15. use App\Entity\Product;
  16. use App\Repository\DeliveryRepository;
  17. use App\Model\Address;
  18. use App\Repository\ParamsRepository;
  19. use App\Repository\LivreurRepository;
  20. use App\Repository\ProductRepository;
  21. use App\Repository\LivraisonRepository;
  22. use App\Repository\OrderRepository;
  23. use App\Services\CartService;
  24. use App\Services\ShippingService;
  25. use Doctrine\ORM\EntityManager;
  26. use Doctrine\ORM\EntityManagerInterface;
  27. use Exception;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\HttpFoundation\Response;
  30. use Symfony\Component\Routing\Annotation\Route;
  31. use Symfony\Component\HttpFoundation\JsonResponse;
  32. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  33. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  34. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  35. use Symfony\Contracts\Translation\TranslatorInterface;
  36. /**
  37.  * @Security("is_granted('ROLE_USER')")
  38.  */
  39. class CartController extends AbstractController
  40. {
  41.     private $stripePublicKey;
  42.     private $stripeSecretKey;
  43.     private $twig;
  44.     private $livraisonRepository;
  45.     private $productRepository;
  46.     private $deliveryRepository;
  47.     private $logger;
  48.     private $session;
  49.     private $translator;
  50.     private $taxService;
  51.     public function __construct(
  52.         LivraisonRepository $livraisonRepository,
  53.         ProductRepository $productRepository,
  54.         DeliveryRepository $deliveryRepository,
  55.         Environment $twig,
  56.         LoggerInterface $logger,
  57.         SessionInterface $session,
  58.         TranslatorInterface $translator,
  59.         TaxService $taxService
  60.     ) {
  61.         if ($_ENV['APP_ENV'] === 'dev') {
  62.             $this->stripePublicKey $_ENV['STRIPE_PK_TEST'];
  63.             $this->stripeSecretKey $_ENV['STRIPE_SK_TEST'];
  64.         }
  65.         else {
  66.             $this->stripePublicKey $_ENV['STRIPE_PK_PROD'];
  67.             $this->stripeSecretKey $_ENV['STRIPE_SK_PROD'];
  68.         }
  69.         $this->twig $twig;
  70.         $this->livraisonRepository $livraisonRepository;
  71.         $this->productRepository $productRepository;
  72.         $this->deliveryRepository $deliveryRepository;
  73.         $this->logger $logger;
  74.         $this->session $session;
  75.         $this->translator $translator;
  76.         $this->taxService $taxService;
  77.     }
  78.     /**
  79.      * @Route("/panier", name="cart_index")
  80.      */
  81.     public function index(
  82.         SessionInterface $session,
  83.         CartService $cartService,
  84.         LivreurRepository $livreurRepository,
  85.         ParamsRepository $paramsRepository,
  86.         PromoteRepository $promoteRepository,
  87.         ShippingService $shippingService,
  88.         Request $request
  89.     ): Response
  90.     {
  91.         /** @var Uid $customer */
  92.         $customer $this->getUser();
  93.         $cart $customer->getCart();
  94.         $cartService->init($cart);
  95.         $shippingService->setCart($cart);
  96.         $shippingAddress $session->get('shippingAddress', new Address());
  97.         $selectedDelivery $session->get('selectedDelivery'null);
  98.         /** Vérification de la disponibilité de chaque produits */
  99.         if ($cartService->checkOutOfStockProducts() > 0) {
  100.             $this->addFlash('danger'$this->translator->trans('cart_controller.messages.out_of_stock_removed'));
  101.             return $this->redirectToRoute('cart_index');
  102.         }
  103.        
  104.         $deliveryPrices $shippingService->getDeliveryPrices($cartService);
  105.         /** Selection de la livraison */
  106.         if ($request->request->get('livraison') !== null) {
  107.             $shippingAddress null;
  108.             $deliveryId $request->request->get('livraison');
  109.             $selectedDelivery $deliveryId === "retrait" || $deliveryId === "aside" ?
  110.                 $deliveryId $this->deliveryRepository->find($deliveryId);
  111.             /** La Poste */
  112.             if ($selectedDelivery instanceof Delivery && $selectedDelivery->getLivreur()->getName() === "la poste") {
  113.                 $shippingAddress = new Address();
  114.                 $shippingAddress->recipient $customer->getFirstname() . ' ' $customer->getLastname();
  115.                 $shippingAddress->addressLine1 $customer->getAddress()->getAddress();
  116.                 $shippingAddress->complement $customer->getAddress()->getComplement();
  117.                 $shippingAddress->postalCode $customer->getAddress()->getPostalCode();
  118.                 $shippingAddress->city $customer->getAddress()->getCity();
  119.                 $shippingAddress->country $customer->getAddress()->getCountry();
  120.             }
  121.             $session->set('shippingAddress'$shippingAddress);
  122.             $session->set('selectedDelivery'$selectedDelivery);
  123.             $session->set('cart',$cart);
  124.             if ($deliveryId === "aside") {
  125.                 $session->set('selectedGifts', []);
  126.             }
  127.             $this->addFlash('success'$this->translator->trans('cart_controller.messages.delivery_modified'));
  128.             $redirectUrl $request->headers->get('referer');
  129.             return $this->redirect($redirectUrl);
  130.         }
  131.         $shippingVAT 0.00;
  132.         if ($selectedDelivery && $selectedDelivery instanceof Delivery) {
  133.             $shippingVAT $selectedDelivery->getPrice() - $this->taxService->getHtPriceFromTtcPrice($selectedDelivery->getPrice());
  134.         }
  135.         $giftPriceLimit = (float)($paramsRepository->findOneBy(['name' => 'gift_limit'])->getValue());
  136.         $numberOfGiftAllowed floor($cartService->getTotalCartPrice() / $giftPriceLimit);
  137.         $selectedGifts $session->get('selectedGifts', []);
  138.         $numberOfGiftSelected count($selectedGifts);
  139.         $freeVinyls $numberOfGiftAllowed $promoteRepository->find(5)->getProducts() : null;
  140.         $livreurs = [
  141.             $livreurRepository->find(1),
  142.             $livreurRepository->find(2),
  143.         ];
  144.         return $this->render('cart/index.html.twig', [
  145.             'current' => 'cart',
  146.             'params' => $paramsRepository->findAll(),
  147.             'cart' => $cartService->getItems(),
  148.             'total' => $cartService->getTotalCartPrice(),
  149.             'totalVAT' => $this->taxService->getIncludingVatFromCart($cart),
  150.             'shippingVAT' => $shippingVAT,
  151.             'livreurs' => $livreurs,
  152.             'shippingPrices' => $deliveryPrices,
  153.             'shippingPrice' => $selectedDelivery,
  154.             'assidable' => $shippingService->isAssidable(),
  155.             'freeVinyls' => $freeVinyls,
  156.             'numberGiftAllowed' => $numberOfGiftAllowed,
  157.             'selectedGifts' => $selectedGifts,
  158.             'numberOfGiftSelected' => $numberOfGiftSelected,
  159.             'tax' => $this->taxService->getTax()
  160.         ]);
  161.     }
  162.     /**
  163.      * @Route("/paiement", name="cart_checkout")
  164.      */
  165.     public function checkout(
  166.         ParamsRepository $paramsRepository,
  167.         CartService $cartService,
  168.         SessionInterface $session,
  169.         Request $request
  170.     ): Response 
  171.     {
  172.         if (!$this->isGranted('ROLE_USER')) {
  173.             $this->addFlash('warning'$this->translator->trans('cart_controller.messages.must_connect'));
  174.             return $this->redirectToRoute('app_login');
  175.         }
  176.         /**  @var Uid $customer */
  177.         $customer $this->getUser();
  178.         $cartService->init($customer->getCart());
  179.         $selectedGifts $session->get('selectedGifts', []);
  180.         $sessionCart $session->get('cart');
  181.         if (!$sessionCart) {
  182.             $this->addFlash('error'$this->translator->trans('cart_controller.messages.error_occurred'));
  183.             return $this->redirectToRoute('cart_index');
  184.         }
  185.         $payementType $request->request->get('options-outlined');
  186.         if ($payementType && $payementType == 'virement') {
  187.             return $this->redirectToRoute('paiement_virement');
  188.         }
  189.         /** Vérification de la disponibilité de chaque produits */
  190.         if ($cartService->checkOutOfStockProducts() > 0) {
  191.             $this->addFlash('danger'$this->translator->trans('cart_controller.messages.out_of_stock_removed'));
  192.             return $this->redirectToRoute('cart_index');
  193.         }
  194.         $selectedDelivery $session->get('selectedDelivery');
  195.         $shippingAddress $session->get('shippingAddress');
  196.         // Retrait en magasin
  197.         if ($selectedDelivery == 'retrait') {
  198.             return $this->redirectToRoute('retrait_magasin');
  199.         }
  200.         if (!$selectedDelivery) {
  201.             $this->addFlash('warning'$this->translator->trans('cart_controller.messages.select_carrier'));
  202.             return $this->redirectToRoute('cart_index');
  203.         }
  204.         if ($selectedDelivery instanceof Delivery) {
  205.             if ($selectedDelivery->getLivreur()->getName() == "mondial relay" && $shippingAddress === null) {
  206.                 $this->addFlash('danger'$this->translator->trans('cart_controller.messages.select_relay_point'));
  207.                 return $this->redirectToRoute('cart_index');
  208.             }
  209.         }
  210.         if ($selectedDelivery == 'aside') {
  211.             $shippingPrice 0;
  212.         }
  213.         else {
  214.             $shippingPrice $selectedDelivery->getPrice();
  215.         }
  216.         $shippingVAT 0.00;
  217.         if ($selectedDelivery instanceof Delivery) {
  218.             $shippingVAT $selectedDelivery->getPrice() - $this->taxService->getHtPriceFromTtcPrice($selectedDelivery->getPrice());
  219.         }
  220.         return $this->render('cart/checkout.html.twig', [
  221.             'current' => 'cart',
  222.             'params' => $paramsRepository->findAll(),
  223.             'cart' => $cartService->getItems(),
  224.             'total' => $cartService->getTotalCartPrice(),
  225.             'shippingPrice' => $shippingPrice,
  226.             'totalVAT' => $this->taxService->getIncludingVatFromCart($sessionCart),
  227.             'shippingVAT' => $shippingVAT,
  228.             'selectedDelivery' => $selectedDelivery,
  229.             'stripePublicKey' => $this->stripePublicKey,
  230.             'typePaiement' => $payementType,
  231.             'selectedGifts' => $selectedGifts,
  232.             'tax' => $this->taxService->getTax(),
  233.         ]);
  234.     }
  235.     /**
  236.      * @Route("/paiement/intent", name="paiement_intent")
  237.      */
  238.     public function createIntent(SessionInterface $sessionCartService $cartService): JsonResponse
  239.     {
  240.         /**  @var Uid $customer */
  241.         $customer $this->getUser();
  242.         $cartService->init($customer->getCart());
  243.         if ($cartService->getTotalCartPrice() <= 0) {
  244.             return new JsonResponse("Error amount must be positive"JsonResponse::HTTP_BAD_REQUEST);
  245.         }
  246.         $stripe = new \Stripe\StripeClient($this->stripeSecretKey);
  247.         $sessionCart $session->get('cart');
  248.         $selectedDelivery $session->get('selectedDelivery');
  249.         
  250.         $shippingPrice $selectedDelivery == "aside" || $selectedDelivery == "retrait" : (float)$selectedDelivery->getPrice();
  251.         $cartAmount = (float)$cartService->getTotalCartPrice() + $shippingPrice;
  252.         Stripe::setApiKey($this->stripeSecretKey);
  253.         $orderRef 'c-' uniqid();
  254.         $productsList = [];
  255.         foreach ($sessionCart->getItems() as $id => $qty) {
  256.             $product $this->productRepository->find($id);
  257.             $productsList[] = $product->getRef();
  258.         }
  259.         $cartRefs implode(','$productsList);
  260.         $paymentIntent $stripe->paymentIntents->create([
  261.             'amount' => ($cartAmount 100),
  262.             'currency' => 'eur',
  263.             'description' => $orderRef,
  264.             'payment_method_types' => ['card'],
  265.             'metadata' => [
  266.                 "customer_id" => $customer->getId(),
  267.                 "customer_mail" => $customer->getEmail(),
  268.                 "cart_refs" => $cartRefs,
  269.             ]
  270.         ]);
  271.         $session->set('paymentIntentId'$paymentIntent->id);
  272.         $output = [
  273.             'clientSecret' => $paymentIntent->client_secret,
  274.             'order' => $orderRef,
  275.             'pi' => $paymentIntent->id,
  276.             'cart' => $productsList,
  277.             'paymentIntent' => $paymentIntent,
  278.         ];
  279.         return new JsonResponse($output);
  280.     }
  281.     /**
  282.      * @Route("/paiement/success/{ref}", name="paiement_success")
  283.      */
  284.     public function paiementSuccess(
  285.         string $ref,
  286.         EntityManagerInterface $manager,
  287.         OrderRepository $orderRepository,
  288.         ParamsRepository $paramsRepository,
  289.         CartService $cartService,
  290.         SessionInterface $session
  291.     ): Response
  292.     {
  293.         /** @var Uid $customer */
  294.         $customer $this->getUser();
  295.         $cartService->init($customer->getCart());
  296.         $now = new DateTimeImmutable();
  297.         //try {
  298.             $order $orderRepository->findOneBy(['ref' => $ref]);
  299.             if ($order->getState() > 0) {
  300.                 return $this->redirectToRoute('cart_index');
  301.             }
  302.             $selectedDelivery $session->get('selectedDelivery');
  303.             if ($selectedDelivery == 'aside') {
  304.                 $order->setState(2);
  305.                 $deliveryPrice 0;
  306.             }
  307.             else {
  308.                 $order->setState(1);
  309.                 $deliveryPrice $order->getShipping();
  310.             }
  311.             $invoice = new Invoice();
  312.             $invoice->setOrdered($order);
  313.             $invoice->setCreatedAt($now);
  314.             $total $order->getAmount() + $deliveryPrice;
  315.             $invoice->setTotal($total);
  316.             $invoice->setTax($order->getTax());
  317.             $manager->persist($invoice);
  318.             $manager->flush();
  319.             $parameters = [
  320.                 'user' => $order->getUser(),
  321.                 'order' => $order,
  322.             ];
  323.             $headers "From:no-reply@mazykkavinyles.fr" "\r\n";
  324.             $headers .= "MIME-Version: 1.0" "\r\n";
  325.             $headers .= "Content-type:text/html;charset=UTF-8" "\r\n";
  326.             try {
  327.                 mail($order->getUser()->getUserIdentifier(), sprintf($this->translator->trans('cart_controller.emails.order_validated'), $order->getRef()), $this->twig->render("cart/order_email.html.twig"$parameters), $headers);
  328.             } catch (\Exception $e) {
  329.                 $this->logger->error("Email not send", ['message' => $e->getMessage()]);
  330.             }
  331.             $session->remove('cart');
  332.             $session->remove('order');
  333.             $session->remove('selectedDelivery');
  334.             $session->remove('shippingAddress');
  335.             $session->remove('selectedGifts');
  336.             $cartService->updateItems([]);
  337.        /* } catch (Exception $e) {
  338.             $this->addFlash('danger', $e->getMessage());
  339.         }*/
  340.         return $this->render('cart/checkout/success.html.twig', [
  341.             'current' => 'cart',
  342.             'params' => $paramsRepository->findAll(),
  343.         ]);
  344.     }
  345.     /**
  346.      * @Route("/paiement/cancel/{pi}", name="paiement_cancel")
  347.      */
  348.     public function paiementCancel($piEntityManagerInterface $managerOrderRepository $orderRepository): JsonResponse
  349.     {
  350.         $stripe = new \Stripe\StripeClient($this->stripeSecretKey);
  351.         $intent $stripe->paymentIntents->retrieve($pi,[]);
  352.         $order $orderRepository->findOneBy(['ref' => $intent->description]);
  353.         $order->setState(4);
  354.         $manager->flush();
  355.         return new JsonResponse("Paiement canceled");
  356.     }
  357.     /**
  358.      * @Route("/paiement/virement", name="paiement_virement")
  359.      */
  360.     public function virement(
  361.         SessionInterface $session,
  362.         ProductRepository $productRepository,
  363.         LivreurRepository $livreurRepository,
  364.         EntityManagerInterface $manager,
  365.         CartService $cartService,
  366.         ParamsRepository $paramsRepository
  367.     ): Response
  368.     {
  369.         if (!$session->get('cart')) {
  370.             return $this->redirectToRoute('cart_checkout');
  371.         }
  372.         $orderRef 'c-' uniqid();
  373.         $cart $session->get('cart');
  374.         $selectedDelivery $session->get('selectedDelivery');
  375.         $shippingAddress $session->get('shippingAddress');
  376.         if ($selectedDelivery instanceof Delivery) {
  377.             if ($selectedDelivery->getLivreur()->getName() == "mondial relay" && $shippingAddress === null) {
  378.                 $this->addFlash('danger'$this->translator->trans('cart_controller.messages.select_relay_point'));
  379.                 return $this->redirectToRoute('cart_index');
  380.             }
  381.         }
  382.         if ($selectedDelivery == "retrait") {
  383.             $livreur null;
  384.         }
  385.         else {
  386.             // Récupération du livreur via le repository
  387.             $livreur $livreurRepository->find($selectedDelivery->getLivreur()->getId());
  388.             if (!$livreur) {
  389.                 throw new \Exception('Livreur non trouvé');
  390.             }
  391.         }
  392.         /** @var Uid $user */
  393.         $user $this->getUser();
  394.         $cartService->init($user->getCart());
  395.         /** Vérification de la disponibilité de chaque produits */
  396.         if ($cartService->checkOutOfStockProducts() == 0) {
  397.             $order = new Order();
  398.             $order->setRef($orderRef);
  399.             $order->setUser($user);
  400.             $order->setCreatedAt(new DateTimeImmutable());
  401.             $order->setAmount($cartService->getTotalCartPrice());
  402.             $order->setHtShipping($this->taxService->getHtPriceFromTtcPrice($selectedDelivery->getPrice()));
  403.             $order->setShipping($selectedDelivery->getPrice());
  404.             $order->setLivreur($livreur);
  405.             $order->setPi('virement');
  406.             $order->setState(0);
  407.             $order->setLinkedTo(null);
  408.             $order->setTax($this->taxService->getTax());
  409.             if($shippingAddress){
  410.                 $order->setAddress([
  411.                     'recipient' => $shippingAddress->recipient,
  412.                     'addressLine1' => $shippingAddress->addressLine1,
  413.                     'complement' => $shippingAddress->complement,
  414.                     'postalCode' => $shippingAddress->postalCode,
  415.                     'city' => $shippingAddress->city,
  416.                     'country' => $shippingAddress->country,
  417.                 ]);
  418.             }
  419.     
  420.             foreach ($cart->getItems() as $id => $qty) {
  421.                 $detail = new Detail();
  422.                 $product $productRepository->find($id);
  423.                 $newQty $product->getQuantity() - $qty;
  424.                 if ($_ENV['APP_ENV'] === 'prod') {
  425.                     $product->setQuantity($newQty);
  426.                 }
  427.                 $detail->setOrderId($order);
  428.                 $detail->setProduct($product);
  429.                 $price $product->getPromo() > $product->getPromo() : $product->getPrice();
  430.                 $htPrice 0.00;
  431.                 if ($product->getCategory()->getName() === 'vinyles') {
  432.                     /** @var Vinyl $vinyl */
  433.                     $vinyl $product;
  434.                     if ($vinyl->getState() === 'neuf') {
  435.                         $htPrice $this->taxService->getHtPriceFromTtcPrice($price);
  436.                     }
  437.                 } else {
  438.                     $htPrice $this->taxService->getHtPriceFromTtcPrice($price);
  439.                 }
  440.                 $detail->setHtPrice($htPrice);
  441.                 $detail->setPrice($price);
  442.                 $detail->setQty($qty);
  443.                 $manager->persist($detail);
  444.                 $order->addDetail($detail);
  445.             }
  446.             // Calcul total HT
  447.             $htAmount $cartService->getTotalCartPrice() - $this->taxService->getIncludingVatFromCart($cart);
  448.             $order->setHtAmount($htAmount);
  449.             // Produits offert
  450.             $selectedGifts $session->get('selectedGifts', []);
  451.             /** @var Product $product */
  452.             foreach ($selectedGifts as $id => $product) {
  453.                 $product $productRepository->find($id);
  454.                 $detail = new Detail();
  455.                 $newQty $product->getQuantity() - 1;
  456.                 if ($_ENV['APP_ENV'] === 'prod') {
  457.                     $product->setQuantity($newQty);
  458.                 }
  459.                 $detail->setOrderId($order);
  460.                 $detail->setProduct($product);
  461.                 $detail->setHtPrice(0.00);
  462.                 $detail->setPrice(0.00);
  463.                 $detail->setQty(1);
  464.                 $order->addDetail($detail);
  465.             }
  466.             $manager->persist($order);
  467.             $manager->flush();
  468.             $cartService->updateItems([]);
  469.     
  470.             /** Envoi mail client */
  471.             $to = [$user->getUserIdentifier()];
  472.             $parameters = [
  473.                 'user' => $user,
  474.                 'order' => $order,
  475.             ];
  476.             $headers "From:no-reply@mazykkavinyles.fr" "\r\n";
  477.             $headers .= "MIME-Version: 1.0" "\r\n";
  478.             $headers .= "Content-type:text/html;charset=UTF-8" "\r\n";
  479.             try {
  480.                 mail($user->getUserIdentifier(),"Commande n° {$order->getRef()} validé - Mazykka Vinyles" ,$this->twig->render("cart/order_email.html.twig"$parameters),$headers);
  481.             } catch (\Exception $e) {
  482.                 $this->logger->error("Email not send", ['message' => $e->getMessage()]);
  483.             }
  484.             $session->remove('shippingAddress');
  485.             $session->remove('selectedDelivery');
  486.             $session->remove('cart');
  487.             $this->addFlash('success'$this->translator->trans('cart_controller.messages.order_saved'));
  488.         }
  489.         else {
  490.             $this->addFlash('danger'$this->translator->trans('cart_controller.messages.out_of_stock_removed'));
  491.             return $this->redirectToRoute('cart_index');
  492.         }
  493.         return $this->render('cart/checkout.html.twig', [
  494.             'current' => 'cart',
  495.             'params' => $paramsRepository->findAll(),
  496.             'cart' => [],
  497.             'total' => 0,
  498.             'typePaiement' => 'virement',
  499.         ]);
  500.     }
  501.     /**
  502.      * @Route("/paiement/retrait-magasin", name="retrait_magasin")
  503.      */
  504.     public function retrait(
  505.         SessionInterface $session,
  506.         ProductRepository $productRepository,
  507.         CartService $cartService,
  508.         EntityManagerInterface $manager,
  509.         ParamsRepository $paramsRepository
  510.     )
  511.     {
  512.         if (!$session->get('cart')) {
  513.             return $this->redirectToRoute('cart_checkout');
  514.         }
  515.         /**  @var Uid $customer */
  516.         $customer $this->getUser();
  517.         $cartService->init($customer->getCart());
  518.         $orderRef 'c-' uniqid();
  519.         $cart $session->get('cart');
  520.         $user $this->getUser();
  521.         if ($cartService->checkOutOfStockProducts() == 0) {
  522.             $order = new Order();
  523.             $order->setRef($orderRef);
  524.             $order->setUser($user);
  525.             $order->setCreatedAt(new DateTimeImmutable());
  526.             $order->setHtAmount($cartService->getTotalCartPrice() - $this->taxService->getIncludingVatFromCart($cart));
  527.             $order->setAmount($cartService->getTotalCartPrice());
  528.             $order->setHtShipping(0.00);
  529.             $order->setShipping(0.00);
  530.             $order->setLivreur(null);
  531.             $order->setPi('retrait');
  532.             $order->setState(0);
  533.             $order->setTax($this->taxService->getTax());
  534.             foreach ($cart->getItems() as $id => $qty) {
  535.                 $detail = new Detail();
  536.                 $product $productRepository->find($id);
  537.                 $newQty $product->getQuantity() - $qty;
  538.                 if ($_ENV['APP_ENV'] === 'prod') {
  539.                     $product->setQuantity($newQty);
  540.                 }
  541.                 $detail->setOrderId($order);
  542.                 $detail->setProduct($product);
  543.                 $price $product->getPromo() > $product->getPromo() : $price $product->getPrice();
  544.                 $htPrice 0.00;
  545.                 if ($product->getCategory()->getName() === 'vinyles') {
  546.                     /** @var Vinyl $vinyl */
  547.                     $vinyl $product;
  548.                     if ($vinyl->getState() === 'neuf') {
  549.                         $htPrice $this->taxService->getHtPriceFromTtcPrice($price);
  550.                     }
  551.                 } else {
  552.                     $htPrice $this->taxService->getHtPriceFromTtcPrice($price);
  553.                 }
  554.                 $detail->setHtPrice($htPrice);
  555.                 $detail->setPrice($price);
  556.                 $detail->setQty($qty);
  557.                 $manager->persist($detail);
  558.                 $order->addDetail($detail);
  559.             }
  560.             // Calcul total HT
  561.             $htAmount $this->taxService->getHtAmountFromOrder($order);
  562.             $order->setHtAmount($htAmount);
  563.             // Produits offert
  564.             $selectedGifts $session->get('selectedGifts', []);
  565.             /** @var Product $product */
  566.             foreach ($selectedGifts as $id => $product) {
  567.                 $product $productRepository->find($id);
  568.                 $detail = new Detail();
  569.                 $newQty $product->getQuantity() - 1;
  570.                 if ($_ENV['APP_ENV'] === 'prod') {
  571.                     $product->setQuantity($newQty);
  572.                 }
  573.                 $detail->setOrderId($order);
  574.                 $detail->setProduct($product);
  575.                 $detail->setPrice(0.00);
  576.                 $detail->setQty(1);
  577.                 $order->addDetail($detail);
  578.             }
  579.             $manager->persist($order);
  580.             $manager->flush();
  581.             $cartService->updateItems([]);
  582.             $this->addFlash('success'$this->translator->trans('cart_controller.messages.order_saved_hold'));
  583.             $parameters = [
  584.                 'user' => $user,
  585.                 'order' => $order,
  586.             ];
  587.             $headers "From:no-reply@mazykkavinyles.fr" "\r\n";
  588.             $headers .= "MIME-Version: 1.0" "\r\n";
  589.             $headers .= "Content-type:text/html;charset=UTF-8" "\r\n";
  590.             try {
  591.                 mail($user->getUserIdentifier(),"Commande n° {$order->getRef()} validé - Mazykka Vinyles" ,$this->twig->render("cart/order_email.html.twig"$parameters),$headers);
  592.             } catch (\Exception $e) {
  593.                 $this->logger->error("Email not send", ['message' => $e->getMessage()]);
  594.             }
  595.             $session->remove('shippingAddress');
  596.             $session->remove('selectedDelivery');
  597.             $session->remove('cart');
  598.         }
  599.         else {
  600.             $this->addFlash('danger'$this->translator->trans('cart_controller.messages.out_of_stock_removed'));
  601.             return $this->redirectToRoute('cart_index');
  602.         }
  603.         return $this->render('cart/checkout.html.twig', [
  604.             'current' => 'cart',
  605.             'params' => $paramsRepository->findAll(),
  606.             'cart' => [],
  607.             'total' => 0,
  608.             'typePaiement' => 'retrait',
  609.         ]);
  610.     }
  611.     /**
  612.      * @Route("/panier/add/{id}", name="cart_add")
  613.      */
  614.     public function add(
  615.         Product $product,
  616.         CartService $cartService,
  617.         Request $request
  618.     ): Response {
  619.         $quantity = isset($_REQUEST['qty']) ? (int) $_REQUEST['qty'] : ;
  620.         /**  @var Uid $customer */
  621.         $customer $this->getUser();
  622.         if(null == $customer || null == $customer->getCart()) {
  623.             $this->addFlash('danger'$this->translator->trans('cart_controller.messages.must_connect_add'));
  624.             $redirectUrl $request->headers->get('referer');
  625.             return $this->redirect($redirectUrl);
  626.         }
  627.         $cartService->init($customer->getCart());
  628.         try {
  629.             $cartService->addProduct($product$quantity);
  630.             $this->addFlash('success'$this->translator->trans('cart_controller.messages.product_added'));
  631.         } catch (Exception $exception) {
  632.             $this->addFlash('danger',
  633.                 sprintf($this->translator->trans('cart_controller.messages.product_not_added'), $exception->getMessage())
  634.             );
  635.             $this->logger->error(sprintf("Product was not added to cart : %s"$exception->getMessage()));
  636.         }
  637.         $redirectUrl $request->headers->get('referer');
  638.         return $this->redirect($redirectUrl);
  639.     }
  640.     /**
  641.      * @Route("/panier/delete/{id}", name="cart_delete")
  642.      */
  643.     public function delete(Product $productCartService $cartServiceRequest $request): Response
  644.     {
  645.         /**  @var Uid $customer */
  646.         $customer $this->getUser();
  647.         $cartService->init($customer->getCart());
  648.         try {
  649.             $cartService->deleteProduct($product);
  650.             $this->addFlash('success'$this->translator->trans('cart_controller.messages.article_deleted'));
  651.         } catch (Exception $exception) {
  652.             $this->addFlash('error'sprintf($this->translator->trans('cart_controller.messages.error_occurred_with'), $exception->getMessage()));
  653.         }
  654.         $redirectUrl $request->headers->get('referer');
  655.         return $this->redirect($redirectUrl);
  656.     }
  657.     /**
  658.      * @Route("/panier/gift/add/{id}", name="cart_add_gift")
  659.      */
  660.     public function addGift(
  661.         Product $product,
  662.         CartService $cartService,
  663.         ParamsRepository $paramsRepository,
  664.         Request $request
  665.     ): Response {
  666.         /**  @var Uid $customer */
  667.         $customer $this->getUser();
  668.         if(null == $customer || null == $customer->getCart()) {
  669.             $this->addFlash('danger'$this->translator->trans('cart_controller.messages.must_connect_add'));
  670.             $redirectUrl $request->headers->get('referer');
  671.             return $this->redirect($redirectUrl);
  672.         }
  673.         $cartService->init($customer->getCart());
  674.         $giftPriceLimit = (float)($paramsRepository->findOneBy(['name' => 'gift_limit'])->getValue());
  675.         $numberOfGiftAllowed floor($cartService->getTotalCartPrice() / $giftPriceLimit);
  676.         $selectedGifts $this->session->get('selectedGifts', []);
  677.         $numberOfGiftSelected count($selectedGifts);
  678.         if ($numberOfGiftAllowed <= $numberOfGiftSelected) {
  679.             $this->addFlash('danger'$this->translator->trans('cart_controller.messages.max_selection_reached'));
  680.             $redirectUrl $request->headers->get('referer');
  681.             return $this->redirect($redirectUrl);
  682.         }
  683.         try {
  684.             $cartService->addGift($product);
  685.             $this->addFlash('success'$this->translator->trans('cart_controller.messages.selection_added'));
  686.         } catch (Exception $exception) {
  687.             $this->addFlash('danger',
  688.                 sprintf($this->translator->trans('cart_controller.messages.product_not_added'), $exception->getMessage())
  689.             );
  690.             $this->logger->error(sprintf("Product was not added to cart : %s"$exception->getMessage()));
  691.         }
  692.         $redirectUrl $request->headers->get('referer');
  693.         return $this->redirect($redirectUrl);
  694.     }
  695.     /**
  696.      * @Route("/panier/gift/delete/{id}", name="cart_delete_gift")
  697.      */
  698.     public function deleteGift(Product $productCartService $cartServiceRequest $request): Response
  699.     {
  700.         /**  @var Uid $customer */
  701.         $customer $this->getUser();
  702.         $cartService->init($customer->getCart());
  703.         try {
  704.             $cartService->deleteGift($product);
  705.             $this->addFlash('success'$this->translator->trans('cart_controller.messages.product_deleted'));
  706.         } catch (Exception $exception) {
  707.             $this->addFlash('error'sprintf($this->translator->trans('cart_controller.messages.error_occurred_with'), $exception->getMessage()));
  708.         }
  709.         $redirectUrl $request->headers->get('referer');
  710.         return $this->redirect($redirectUrl);
  711.     }
  712.     /**
  713.      * @Route("/panier/gift/unload", name="cart_unload_gift")
  714.      */
  715.     public function unloadGift(Request $request): Response
  716.     {
  717.         $this->session->set('selectedGifts', []);
  718.         $redirectUrl $request->headers->get('referer');
  719.         return $this->redirect($redirectUrl);
  720.     }
  721.     private function checkQty($sessionCartProductRepository $productRepositorySessionInterface $session): array
  722.     {
  723.         
  724.         $cart $sessionCart->getItems();
  725.         $hsProduct = [];
  726.         foreach ($cart as $p => $qty) {
  727.             $product $productRepository->find($p);
  728.             if($product){
  729.                 if ($product->getQuantity() < 1) {
  730.                     $hsProduct[] = $product;
  731.                     $sessionCart['qty'] -= $qty;
  732.                     $price $product->getPromo() > $product->getPromo() : $product->getPrice();
  733.                     $sessionCart['total'] -= ($price $qty);
  734.                     unset($cart[$product->getId()]);
  735.                     $sessionCart['items'] = $cart;
  736.                     $session->set('cart',$sessionCart);
  737.                 }
  738.             }
  739.         }
  740.         return $hsProduct;
  741.     }
  742.     /**
  743.      * @Route("/panier/add-shipping-address", name="cart_add_shipping_address")
  744.      */
  745.     public function addShippingAddress(SessionInterface $session): JsonResponse
  746.     {
  747.         $data $_POST;
  748.         if($data != null){
  749.             $address = new Address();
  750.             $address->recipient $data['Nom'];
  751.             $address->addressLine1 $data['Adresse1'];
  752.             $address->postalCode $data['CP'];
  753.             $address->city $data['Ville'];
  754.             $address->country $data['Pays'];
  755.         } else {
  756.             $address null;
  757.         }
  758.         
  759.         $session->set('shippingAddress'$address);
  760.         $this->addFlash('success''Livraison modifiée');
  761.         return new JsonResponse(["Address added"]);
  762.     }
  763.     private function saveOrder(
  764.         SessionInterface $session
  765.         string $pi
  766.         LivraisonRepository $livraisonRepository,
  767.         ProductRepository $productRepository,
  768.         EntityManager $manager
  769.     )
  770.     {
  771.         $stripe = new \Stripe\StripeClient($this->stripeSecretKey);
  772.         $intent $stripe->paymentIntents->retrieve($pi,[]);
  773.         $now = new DateTimeImmutable();
  774.         $cart $session->get('cart');
  775.         $user $this->getUser();
  776.         $order = new Order();
  777.         $order->setRef($intent->description);
  778.         $order->setUser($user);
  779.         $order->setCreatedAt($now);
  780.         $order->setAmount($cart['total']);
  781.         $order->setPi($pi);
  782.         if ($cart['shipping'] == 'aside') {
  783.             $order->setShipping(0.00);
  784.             $order->setState(2);
  785.         }
  786.         else {
  787.             $livraison $livraisonRepository->find($cart['shipping']);
  788.             $order->setShipping($livraison->getPrice());
  789.             $order->setLivreur($livraison->getLivreur());
  790.             if($cart['address']){
  791.                 $order->setAddress($cart['address']);
  792.             }
  793.             $order->setState(1);
  794.         }
  795.         $manager->persist($order);
  796.         foreach ($cart['items'] as $id => $qty) {
  797.             $detail = new Detail();
  798.             $product $productRepository->find($id);
  799.             $newQty $product->getQuantity() - $qty;
  800.             if ($_ENV['APP_ENV'] === 'prod') {
  801.                 $product->setQuantity($newQty);
  802.             }
  803.             $detail->setOrderId($order);
  804.             $detail->setProduct($product);
  805.             $price $product->getPromo() > $product->getPromo() : $price $product->getPrice();
  806.             $detail->setPrice($price);
  807.             $detail->setQty($qty);
  808.             $manager->persist($detail);
  809.             $order->addDetail($detail);
  810.         }
  811.     }
  812.     
  813.     /**
  814.      * @Route("/paiement/preorder", name="preorder")
  815.      */
  816.     public function preorder(
  817.         SessionInterface $session,
  818.         CartService $cartService,
  819.         LivreurRepository $livreurRepository,
  820.         ProductRepository $productRepository,
  821.         OrderRepository $orderRepository,
  822.         EntityManagerInterface $manager
  823.     ): JsonResponse {
  824.         /**  @var Uid $customer */
  825.         $customer $this->getUser();
  826.         $cartService->init($customer->getCart());
  827.         $cart $session->get('cart');
  828.         if ($cartService->getTotalCartPrice() <= 0) {
  829.             $this->logger->critical('Error : amount must be positive');
  830.             return new JsonResponse('Error : amount must be positive'Response::HTTP_BAD_REQUEST);
  831.         }
  832.         $pi $session->get('paymentIntentId');
  833.         $selectedDelivery $session->get('selectedDelivery');
  834.         if ($selectedDelivery == "retrait" || $selectedDelivery == "aside") {
  835.             $livreur null;
  836.             $shippingPrice 0;
  837.         }
  838.         else {
  839.             $livreur $livreurRepository->find($selectedDelivery->getLivreur()->getId());
  840.             $shippingPrice $selectedDelivery->getPrice();
  841.         }
  842.         $shippingAddress $session->get('shippingAddress');
  843.         try {
  844.             $stripe = new \Stripe\StripeClient($this->stripeSecretKey);
  845.             $intent $stripe->paymentIntents->retrieve($pi,[]);
  846.             $now = new DateTimeImmutable();
  847.             if(!$orderRepository->findOneBy(['pi' => $pi])) {
  848.                 $order = new Order();
  849.                 $order->setRef($intent->description);
  850.                 $order->setUser($customer);
  851.                 $order->setCreatedAt($now);
  852.                 $order->setAmount($cartService->getTotalCartPrice());
  853.                 $order->setPi($pi);
  854.                 $order->setShipping($shippingPrice);
  855.                 $order->setLivreur($livreur);
  856.                 if($shippingAddress){
  857.                     $order->setAddress([
  858.                         'recipient' => $shippingAddress->recipient,
  859.                         'addressLine1' => $shippingAddress->addressLine1,
  860.                         'postalCode' => $shippingAddress->postalCode,
  861.                         'city' => $shippingAddress->city,
  862.                         'country' => $shippingAddress->country,
  863.                     ]);
  864.                 }
  865.                 $order->setState(0);
  866.                 foreach ($cart->getItems() as $id => $qty) {
  867.                     $detail = new Detail();
  868.                     $product $productRepository->find($id);
  869.                     $newQty $product->getQuantity() - $qty;
  870.                     if ($_ENV['APP_ENV'] === 'prod') {
  871.                         $product->setQuantity($newQty);
  872.                     }
  873.                     $detail->setOrderId($order);
  874.                     $detail->setProduct($product);
  875.                     $price $product->getPromo() > $product->getPromo() : $price $product->getPrice();
  876.                     $detail->setPrice($price);
  877.                     $detail->setQty($qty);
  878.                     $order->addDetail($detail);
  879.                 }
  880.                 // Produits offert
  881.                 $selectedGifts $session->get('selectedGifts', []);
  882.                 /** @var Product $product */
  883.                 foreach ($selectedGifts as $id => $product) {
  884.                     $product $productRepository->find($id);
  885.                     $detail = new Detail();
  886.                     $newQty $product->getQuantity() - 1;
  887.                     if ($_ENV['APP_ENV'] === 'prod') {
  888.                         $product->setQuantity($newQty);
  889.                     }
  890.                     $detail->setOrderId($order);
  891.                     $detail->setProduct($product);
  892.                     $detail->setPrice(0.00);
  893.                     $detail->setQty(1);
  894.                     $order->addDetail($detail);
  895.                 }
  896.                 $manager->persist($order);
  897.             }
  898.             else {
  899.                 $order $orderRepository->findOneBy(['pi' => $pi]);
  900.             }
  901.             $manager->flush();
  902.             $cartService->updateItems([]);
  903.             $this->logger->info("Pre-order " $order->getRef() . " saved");
  904.             // Preorder mail sending
  905.             $parameters = [
  906.                 'user' => $order->getUser(),
  907.                 'order' => $order,
  908.             ];
  909.             $headers "From:no-reply@mazykkavinyles.fr" "\r\n";
  910.             $headers .= "MIME-Version: 1.0" "\r\n";
  911.             $headers .= "Content-type:text/html;charset=UTF-8" "\r\n";
  912.             mail(
  913.                 $order->getUser()->getUserIdentifier(),
  914.                 sprintf($this->translator->trans('cart_controller.emails.order_registered'), $order->getRef()),
  915.                 $this->twig->render("cart/pre_order_email.html.twig"$parameters),
  916.                 $headers
  917.             );
  918.         } catch (Exception $exception) {
  919.             $this->logger->error($exception->getMessage());
  920.             return new JsonResponse('Error on pre-order'Response::HTTP_BAD_REQUEST);
  921.         }
  922.         return new JsonResponse(['response' => 200]);
  923.     }
  924. }