src/Controller/EcommerceController.php line 79

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Address;
  4. use App\Entity\Cart;
  5. use App\Entity\CartProduct;
  6. use App\Entity\Category;
  7. use App\Entity\EcommerceOrder;
  8. use App\Entity\PaymentMode;
  9. use App\Entity\Product;
  10. use App\Entity\PromoCode;
  11. use App\Entity\Shipping;
  12. use App\Entity\ShippingPrice;
  13. use App\Repository\CartRepository;
  14. use App\Service\Order;
  15. use App\Service\Klaviyo;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use Stripe\StripeClient;
  18. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  19. use Symfony\Component\Routing\Annotation\Route;
  20. use Symfony\Component\HttpFoundation\JsonResponse;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpFoundation\Response;
  23. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  24. use Symfony\Component\VarDumper\VarDumper;
  25. use App\Entity\User;
  26. use App\Service\FacebookConversion;
  27. use App\Service\RedditConversion;
  28. /**
  29.  * Default controller.
  30.  *
  31.  * @Route("/shop", requirements={"_locale" = "en|fr"})
  32.  */
  33. class EcommerceController extends AbstractController
  34. {
  35.     /**
  36.      * @Route("/", name="shop",  options={"sitemap": true, "priority": 1, "changefreq": "yearly"})
  37.      */
  38.     public function shopAction(Request $requestEntityManagerInterface $em)
  39.     {
  40.         $pack $em->getRepository(Product::class)->find(1);
  41.         $lore $em->getRepository(Product::class)->find(10);
  42.         $tome $em->getRepository(Product::class)->find(11);
  43.         $categories $em->getRepository(Category::class)->findBy(['deletedAt' => null], ['sort' => 'ASC']);
  44.         $currenciesList = [
  45.             ['label' => 'EUR €''value' => 'euros''selected' => $request->getSession()->get('currency') == 'euros'],
  46.             ['label' => 'USD $''value' => 'dollars''selected' => $request->getSession()->get('currency') == 'dollars'],
  47.             ['label' => 'GBP £''value' => 'pounds''selected' => $request->getSession()->get('currency') == 'pounds'],
  48.         ];
  49.         return $this->render('app/ecommerce/list.html.twig', [
  50.             'categories' => $categories,
  51.             'pack' => $pack,
  52.             'lore' => $lore,
  53.             'tome' => $tome,
  54.             'currenciesList' => $currenciesList
  55.         ]);
  56.     }
  57.     /**
  58.      * @Route("/product/{id}/{slug}", name="shop_product",  options={"sitemap": false, "priority": 1, "changefreq": "yearly"})
  59.      */
  60.     public function shopItemAction(Request $requestEntityManagerInterface $emProduct $product)
  61.     {
  62.         if (!$product || $product->isDeleted() || !$product->isDisplayOnShop()) {
  63.             return $this->redirectToRoute('shop');
  64.         }
  65.         return $this->render('app/ecommerce/show.html.twig', [
  66.             'product' => $product,
  67.         ]);
  68.     }
  69.     /**
  70.      * @Route("/cart/add/{id}", methods={"GET"}, name="add_to_cart", options={"sitemap": false})
  71.      *
  72.      */
  73.     public function addToCartAction(Request $requestProduct $productOrder $orderServiceEntityManagerInterface $em)
  74.     {
  75.         $repoCart $em->getRepository('App:Cart');
  76.         /** @var User $user * */
  77.         $user $this->getUser();
  78.         $cart $repoCart->findOneBy(array("session" => User::getSessionId($request), "ordered" => false));
  79.         if (!$cart instanceof Cart) {
  80.             $cart = new Cart();
  81.             $cart->setCurrency($request->getSession()->get('currency''euros'));
  82.             $cart->setUser($user);
  83.             $cart->setOrdered(false);
  84.             $cart->setSession(User::getSessionId($request));
  85.             $cartProduct = new CartProduct();
  86.             $orderService->addToCart($cartProduct$cart$product);
  87.             $em->persist($cart);
  88.         } else {
  89.             $cartProducts $cart->getCartProducts();
  90.             $find false;
  91.             /** @var CartProduct $cartProduct */
  92.             foreach ($cartProducts as $cartProduct) {
  93.                 if (($cartProduct->getProduct()->getId() === $product->getId())) {
  94.                     $find true;
  95.                 }
  96.             }
  97.             if (false === $find) {
  98.                 // this logic is specific to the current state of Amsel Suite, it makes no sense to have a cart with multiple products
  99.                 if ($cart->getCartProducts()->count() > 0) {
  100.                     foreach ($cartProducts as $cartProduct) {
  101.                         $cart->removeCartProduct($cartProduct);
  102.                         $em->remove($cartProduct);
  103.                     }
  104.                 }
  105.                 $cartProduct = new CartProduct();
  106.                 $orderService->addToCart($cartProduct$cart$product);
  107.                 $em->persist($cart);
  108.             }
  109.         }
  110.         $em->flush();
  111.         $orderService->updateCart($request);
  112.         return $this->redirectToRoute("shop_cart");
  113.     }
  114.     /**
  115.      * @Route("/cart/remove/{id}", methods={"GET"}, name="remove_to_cart", options={"sitemap": false})
  116.      *
  117.      */
  118.     public function removeToCartAction(Request $requestCartProduct $cartProductOrder $orderServiceEntityManagerInterface $em)
  119.     {
  120.         $em->remove($cartProduct);
  121.         $em->flush();
  122.         $orderService->updateCart($request);
  123.         return $this->redirectToRoute("homepage");
  124.     }
  125.     /**
  126.      * @Route("/cart", name="shop_cart",  options={"sitemap": false})
  127.      */
  128.     public function cartAction(Request $requestOrder $orderServiceEntityManagerInterface $em)
  129.     {
  130.         $repoCart $em->getRepository('App:Cart');
  131.         $orderService->updateCart($request);
  132.         /** @var Cart $cart */
  133.         $cart $repoCart->findOneBy(array(
  134.             "session" => User::getSessionId($request),
  135.             "ordered" => false
  136.         ));
  137.         if ($cart instanceof Cart) {
  138.             $cartProducts $cart->getCartProducts();
  139.         } else {
  140.             $cartProducts null;
  141.         }
  142.         if ($request->getMethod() == "POST") {
  143.             if ($cart instanceof Cart) {
  144.                 $recipient $request->get('_recipient');
  145.                 $cart->setRecipient($recipient);
  146.                 $em->persist($cart);
  147.                 $em->flush();
  148.                 return $this->redirectToRoute('shop_cart_products');
  149.             } else {
  150.                 return $this->redirectToRoute('homepage');
  151.             }
  152.         }
  153.         return $this->render("app/ecommerce/cart.html.twig", ['cartProducts' => $cartProducts]);
  154.     }
  155.     /**
  156.      * @Route("/cart/products", name="shop_cart_products",  options={"sitemap": false})
  157.      */
  158.     public function cartProductsAction(Request $requestOrder $orderServiceEntityManagerInterface $em)
  159.     {
  160.         $repoCart $em->getRepository('App:Cart');
  161.         $orderService->updateCart($request);
  162.         /** @var Cart $cart */
  163.         $cart $repoCart->findOneBy(array(
  164.             "session" => User::getSessionId($request),
  165.             "ordered" => false
  166.         ));
  167.         if ($cart instanceof Cart) {
  168.             $cartProducts $cart->getCartProducts();
  169.         } else {
  170.             $cartProducts null;
  171.         }
  172.         if ($cartProducts) {
  173.             $alreadyExist false;
  174.             foreach ($cartProducts as $cartProduct) {
  175.                 if ($this->getUser()->existProduct($cartProduct->getProduct())) {
  176.                     $alreadyExist true;
  177.                 }
  178.             }
  179.             if ($alreadyExist == false || $cart->getRecipient() != null) {
  180.                 return $this->render("app/ecommerce/cart_products.html.twig", array(
  181.                     'cartProducts' => $cartProducts,
  182.                     'cart' => $cart
  183.                 ));
  184.             }
  185.             return $this->redirectToRoute('shop_cart');
  186.         }
  187.         return $this->redirectToRoute('homepage');
  188.     }
  189.     /**
  190.      * @Route("/checkout", name="checkout",  options={"sitemap": false})
  191.      */
  192.     public function checkoutAction(Request $requestOrder $orderServiceEntityManagerInterface $em)
  193.     {
  194.         if($request->get('cgv'0) !=|| $request->get('delay'0) != 1){
  195.             $params = [];
  196.             if($request->get('cgv'0) !=1){
  197.                 $params['cgv'] = "no";
  198.             }
  199.             if($request->get('delay'0) !=1){
  200.                 $params['delay'] = "no";
  201.             }
  202.             return $this->redirectToRoute('shop_cart_products'$params);
  203.         }
  204.         $stripe_public_key $this->getParameter('stripe_public_key');
  205.         $repoCart $em->getRepository('App:Cart');
  206.         $orderService->updateCart($request);
  207.         /** @var Cart $cart */
  208.         $cart $repoCart->findOneBy(array(
  209.             "session" => User::getSessionId($request),
  210.             "ordered" => false
  211.         ));
  212.         if ($cart instanceof Cart) {
  213.             $alreadyExist false;
  214.             $price 0;
  215.             /** @var CartProduct $cartProduct */
  216.             foreach ($cart->getCartProducts() as $cartProduct) {
  217.                 $price += $cartProduct->getActualPrice($cart->getCurrency()) * 100 $cartProduct->getQuantity();
  218.                 if ($this->getUser()->existProduct($cartProduct->getProduct())) {
  219.                     $alreadyExist true;
  220.                 }
  221.             }
  222.             $user $this->getUser();
  223.             $cart->setUser($user);
  224.             $em->persist($cart);
  225.             $em->flush();
  226.             if ($alreadyExist == false || $cart->getRecipient() != null) {
  227.                 return $this->render('app/ecommerce/checkout.html.twig', ['cart' => $cart'stripe_public_key' => $stripe_public_key'amount' => $price]);
  228.             } else {
  229.                 return $this->redirectToRoute('shop_cart');
  230.             }
  231.         }
  232.         return $this->redirectToRoute('homepage');
  233.     }
  234.     private function getAcronymFromCurrency($currency)
  235.     {
  236.         switch ($currency) {
  237.             case 'euros':
  238.                 return 'eur';
  239.             case 'dollars':
  240.                 return 'usd';
  241.             case 'pounds':
  242.                 return 'gbp';
  243.             default:
  244.                 return 'eur';
  245.         }
  246.     }
  247.     /**
  248.      * @Route("/checkout/create-session/{id}", name="checkout_create_session",  options={"sitemap": false})
  249.      */
  250.     public function checkoutLoadAction(Request $requestCart $cart)
  251.     {
  252.         $stripe_secret_key $this->getParameter('stripe_secret_key');
  253.         $items = [];
  254.         $currencyAcronym $this->getAcronymFromCurrency($cart->getCurrency());
  255.         /** @var CartProduct $cartProduct */
  256.         foreach ($cart->getCartProducts() as $cartProduct) {
  257.             $item = [
  258.                 'price_data' => [
  259.                     'currency' => $currencyAcronym,
  260.                     'product_data' => [
  261.                         'name' => $cartProduct->getProduct()->translate()->getTitle(),
  262.                         'images' => [$request->getUriForPath($cartProduct->getProduct()->getFirstPicture()->getPath())],
  263.                     ],
  264.                     'unit_amount' => $cartProduct->getActualPrice($cart->getCurrency()) * 100,
  265.                 ],
  266.                 'quantity' => $cartProduct->getQuantity(),
  267.             ];
  268.             $items[] = $item;
  269.         }
  270.         $stripe = new StripeClient([
  271.             "api_key" => $stripe_secret_key
  272.         ]);
  273.         $checkout_session $stripe->checkout->sessions->create([
  274.             'customer_email' => $cart->getUser()->getEmail(),
  275.             'line_items' => $items,
  276.             'locale' => $request->getLocale(),
  277.             'invoice_creation' => ['enabled' => true],
  278.             'automatic_tax' => ['enabled' => true],
  279.             'mode' => 'payment',
  280.             'ui_mode' => 'embedded',
  281.             'allow_promotion_codes' => true,
  282.             'return_url' => $this->generateUrl('checkout_return', ['id' => $cart->getId()], UrlGeneratorInterface::ABSOLUTE_URL) . '?session_id={CHECKOUT_SESSION_ID}',
  283.         ]);
  284.         return new JsonResponse([
  285.             'clientSecret' => $checkout_session->client_secret
  286.         ]);
  287.     }
  288.     /**
  289.      * @Route("/checkout/{id}/return", name="checkout_return",  options={"sitemap": false})
  290.      */
  291.     public function checkoutReturnAction(Request $requestCart $cartOrder $orderKlaviyo $klaviyoServiceFacebookConversion $fbConversionRedditConversion $redditConversion)
  292.     {
  293.         $stripe_secret_key $this->getParameter('stripe_secret_key');
  294.         $stripe = new StripeClient([
  295.             "api_key" => $stripe_secret_key
  296.         ]);
  297.         try {
  298.             $session $stripe->checkout->sessions->retrieve($request->get('session_id'));
  299.             if ($session->status == "complete") {
  300.                 $listProducts = [];
  301.                 $totalPrice 0;
  302.                 /** @var CartProduct $cartProduct */
  303.                 foreach ($cart->getCartProducts() as $cartProduct) {
  304.                     $totalPrice += $cartProduct->getActualPrice($cart->getCurrency()) * $cartProduct->getQuantity();
  305.                     $listProducts[] = [
  306.                         'product_id' => $cartProduct->getProduct()->getId(),
  307.                         'product_name' => $cartProduct->getProduct()->translate()->getTitle(),
  308.                         'price' => $cartProduct->getActualPrice($cart->getCurrency()),
  309.                         'quantity' => $cartProduct->getQuantity()
  310.                     ];
  311.                 }
  312.                 $orderEntity $order->saveOrder($cart$session);
  313.                 $currencyAcronym $this->getAcronymFromCurrency($cart->getCurrency());
  314.                 // sending purchase event to Klaviyo
  315.                 $klaviyoService->event('Purchase', [
  316.                     'price' => $totalPrice,
  317.                 ], $cart->getUser()->getEmail());
  318.                 try {
  319.                     $userData = [
  320.                         'em' => $fbConversion->prepareEmail($cart->getUser()->getEmail()),
  321.                     ];
  322.                     $session $request->getSession();
  323.                     if ($session->has('fbclid')) {
  324.                         $userData['fbc'] = $session->get('fbclid');
  325.                     }
  326.                     $currencyAcronym $this->getAcronymFromCurrency($cart->getCurrency());
  327.                     $fbConversion->sendEvent('Purchase',
  328.                         $userData,
  329.                         [
  330.                             'value' => $totalPrice,
  331.                             'currency' => $currencyAcronym,
  332.                         ]
  333.                     );
  334.                 } catch (\Exception $e) {
  335.                     // Handle exception (log it, rethrow it, etc.)
  336.                 }
  337.                 try {
  338.                     $userData = [
  339.                         'email' => $redditConversion->prepareEmail($cart->getUser()->getEmail()),
  340.                     ];
  341.                     $session $request->getSession();
  342.                     $clickId null;
  343.                     if ($session->has('rdt_cid')) {
  344.                         $clickId $session->get('rdt_cid');
  345.                     }
  346.                     $currencyAcronym $this->getAcronymFromCurrency($cart->getCurrency());
  347.                     $redditConversion->sendEvent('Purchase',
  348.                         $userData,
  349.                         $clickId,
  350.                         [
  351.                             'value_decimal' => $totalPrice,
  352.                             'currency' => $currencyAcronym,
  353.                         ]
  354.                     );
  355.                 } catch (\Exception $e) {
  356.                     // Handle exception (log it, rethrow it, etc.)
  357.                 }
  358.                 return $this->render('app/ecommerce/checkout_ok.html.twig', ['order' => $orderEntity'order_products' => $listProducts]);
  359.             } else {
  360.                 return $this->redirectToRoute('checkout');
  361.             }
  362.         } catch (Error $e) {
  363.             return $this->render('app/ecommerce/checkout_error.html.twig', ['error' => $e->getMessage()]);
  364.         }
  365.     }
  366. }