<?php
namespace App\Controller;
use App\Entity\Address;
use App\Entity\Cart;
use App\Entity\CartProduct;
use App\Entity\Category;
use App\Entity\EcommerceOrder;
use App\Entity\PaymentMode;
use App\Entity\Product;
use App\Entity\PromoCode;
use App\Entity\Shipping;
use App\Entity\ShippingPrice;
use App\Repository\CartRepository;
use App\Service\Order;
use Doctrine\ORM\EntityManagerInterface;
use Stripe\StripeClient;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\VarDumper\VarDumper;
use App\Entity\User;
/**
* Default controller.
*
* @Route("/shop", requirements={"_locale" = "en|fr"})
*/
class EcommerceController extends AbstractController
{
/**
* @Route("/", name="shop", options={"sitemap": true, "priority": 1, "changefreq": "yearly"})
*/
public function shopAction(Request $request, EntityManagerInterface $em)
{
$pack = $em->getRepository(Product::class)->find(1);
$lore = $em->getRepository(Product::class)->find(10);
$tome = $em->getRepository(Product::class)->find(11);
$categories = $em->getRepository(Category::class)->findBy(['deletedAt' => null], ['sort' => 'ASC']);
return $this->render('app/ecommerce/list.html.twig', ['categories' => $categories, 'pack' => $pack, 'lore' => $lore, 'tome' => $tome]);
}
/**
* @Route("/product/{id}/{slug}", name="shop_product", options={"sitemap": false, "priority": 1, "changefreq": "yearly"})
*/
public function shopItemAction(Request $request, EntityManagerInterface $em, Product $product)
{
if (!$product || $product->isDeleted() || !$product->isDisplayOnShop()) {
return $this->redirectToRoute('shop');
}
return $this->render('app/ecommerce/show.html.twig', [
'product' => $product,
]);
}
/**
* @Route("/cart/add/{id}", methods={"GET"}, name="add_to_cart", options={"sitemap": false})
*
*/
public function addToCartAction(Request $request, Product $product, Order $orderService, EntityManagerInterface $em)
{
$repoCart = $em->getRepository('App:Cart');
/** @var User $user * */
$user = $this->getUser();
$cart = $repoCart->findOneBy(array("session" => User::getSessionId($request), "ordered" => false));
if (!$cart instanceof Cart) {
$cart = new Cart();
$cart->setUser($user);
$cart->setOrdered(false);
$cart->setSession(User::getSessionId($request));
$cartProduct = new CartProduct();
$orderService->addToCart($cartProduct, $cart, $product);
$em->persist($cart);
} else {
$cartProducts = $cart->getCartProducts();
$find = false;
/** @var CartProduct $cartProduct */
foreach ($cartProducts as $cartProduct) {
if (($cartProduct->getProduct()->getId() === $product->getId())) {
$find = true;
}
}
if (false === $find) {
// this logic is specific to the current state of Amsel Suite, it makes no sense to have a cart with multiple products
if ($cart->getCartProducts()->count() > 0) {
foreach ($cartProducts as $cartProduct) {
$cart->removeCartProduct($cartProduct);
$em->remove($cartProduct);
}
}
$cartProduct = new CartProduct();
$orderService->addToCart($cartProduct, $cart, $product);
$em->persist($cart);
}
}
$em->flush();
$orderService->updateCart($request);
return $this->redirectToRoute("shop_cart");
}
/**
* @Route("/cart/remove/{id}", methods={"GET"}, name="remove_to_cart", options={"sitemap": false})
*
*/
public function removeToCartAction(Request $request, CartProduct $cartProduct, Order $orderService, EntityManagerInterface $em)
{
$em->remove($cartProduct);
$em->flush();
$orderService->updateCart($request);
return $this->redirectToRoute("homepage");
}
/**
* @Route("/cart", name="shop_cart", options={"sitemap": false})
*/
public function cartAction(Request $request, Order $orderService, EntityManagerInterface $em)
{
$repoCart = $em->getRepository('App:Cart');
$orderService->updateCart($request);
/** @var Cart $cart */
$cart = $repoCart->findOneBy(array(
"session" => User::getSessionId($request),
"ordered" => false
));
if ($cart instanceof Cart) {
$cartProducts = $cart->getCartProducts();
} else {
$cartProducts = null;
}
if ($request->getMethod() == "POST") {
if ($cart instanceof Cart) {
$recipient = $request->get('_recipient');
$cart->setRecipient($recipient);
$em->persist($cart);
$em->flush();
return $this->redirectToRoute('shop_cart_products');
} else {
return $this->redirectToRoute('homepage');
}
}
return $this->render("app/ecommerce/cart.html.twig", ['cartProducts' => $cartProducts]);
}
/**
* @Route("/cart/products", name="shop_cart_products", options={"sitemap": false})
*/
public function cartProductsAction(Request $request, Order $orderService, EntityManagerInterface $em)
{
$repoCart = $em->getRepository('App:Cart');
$orderService->updateCart($request);
/** @var Cart $cart */
$cart = $repoCart->findOneBy(array(
"session" => User::getSessionId($request),
"ordered" => false
));
if ($cart instanceof Cart) {
$cartProducts = $cart->getCartProducts();
} else {
$cartProducts = null;
}
if ($cartProducts) {
$alreadyExist = false;
foreach ($cartProducts as $cartProduct) {
if ($this->getUser()->existProduct($cartProduct->getProduct())) {
$alreadyExist = true;
}
}
if ($alreadyExist == false || $cart->getRecipient() != null) {
return $this->render("app/ecommerce/cart_products.html.twig", array(
'cartProducts' => $cartProducts,
'cart' => $cart
));
}
return $this->redirectToRoute('shop_cart');
}
return $this->redirectToRoute('homepage');
}
/**
* @Route("/checkout", name="checkout", options={"sitemap": false})
*/
public function checkoutAction(Request $request, Order $orderService, EntityManagerInterface $em)
{
if($request->get('cgv', 0) !=1 || $request->get('delay', 0) != 1){
$params = [];
if($request->get('cgv', 0) !=1){
$params['cgv'] = "no";
}
if($request->get('delay', 0) !=1){
$params['delay'] = "no";
}
return $this->redirectToRoute('shop_cart_products', $params);
}
$stripe_public_key = $this->getParameter('stripe_public_key');
$repoCart = $em->getRepository('App:Cart');
$orderService->updateCart($request);
/** @var Cart $cart */
$cart = $repoCart->findOneBy(array(
"session" => User::getSessionId($request),
"ordered" => false
));
if ($cart instanceof Cart) {
$alreadyExist = false;
$price = 0;
/** @var CartProduct $cartProduct */
foreach ($cart->getCartProducts() as $cartProduct) {
$price += $cartProduct->getActualPrice() * 100 * $cartProduct->getQuantity();
if ($this->getUser()->existProduct($cartProduct->getProduct())) {
$alreadyExist = true;
}
}
$user = $this->getUser();
$cart->setUser($user);
$em->persist($cart);
$em->flush();
if ($alreadyExist == false || $cart->getRecipient() != null) {
return $this->render('app/ecommerce/checkout.html.twig', ['cart' => $cart, 'stripe_public_key' => $stripe_public_key, 'amount' => $price]);
} else {
return $this->redirectToRoute('shop_cart');
}
}
return $this->redirectToRoute('homepage');
}
/**
* @Route("/checkout/create-session/{id}", name="checkout_create_session", options={"sitemap": false})
*/
public function checkoutLoadAction(Request $request, Cart $cart)
{
$stripe_secret_key = $this->getParameter('stripe_secret_key');
$items = [];
/** @var CartProduct $cartProduct */
foreach ($cart->getCartProducts() as $cartProduct) {
$item = [
'price_data' => [
'currency' => 'eur',
'product_data' => [
'name' => $cartProduct->getProduct()->translate()->getTitle(),
'images' => [$request->getUriForPath($cartProduct->getProduct()->getFirstPicture()->getPath())],
],
'unit_amount' => $cartProduct->getActualPrice() * 100,
],
'quantity' => $cartProduct->getQuantity(),
];
$items[] = $item;
}
$stripe = new StripeClient([
"api_key" => $stripe_secret_key
]);
$checkout_session = $stripe->checkout->sessions->create([
'line_items' => $items,
'locale' => $request->getLocale(),
'invoice_creation' => ['enabled' => true],
'automatic_tax' => ['enabled' => true],
'mode' => 'payment',
'ui_mode' => 'embedded',
'return_url' => $this->generateUrl('checkout_return', ['id' => $cart->getId()], UrlGeneratorInterface::ABSOLUTE_URL) . '?session_id={CHECKOUT_SESSION_ID}',
]);
return new JsonResponse([
'clientSecret' => $checkout_session->client_secret
]);
}
/**
* @Route("/checkout/{id}/return", name="checkout_return", options={"sitemap": false})
*/
public function checkoutReturnAction(Request $request, Cart $cart, Order $order)
{
$stripe_secret_key = $this->getParameter('stripe_secret_key');
$stripe = new StripeClient([
"api_key" => $stripe_secret_key
]);
try {
$session = $stripe->checkout->sessions->retrieve($request->get('session_id'));
if ($session->status == "complete") {
$listProducts = [];
/** @var CartProduct $cartProduct */
foreach ($cart->getCartProducts() as $cartProduct) {
$listProducts[] = [
'product_id' => $cartProduct->getProduct()->getId(),
'product_name' => $cartProduct->getProduct()->translate()->getTitle(),
'price' => $cartProduct->getActualPrice(),
'quantity' => $cartProduct->getQuantity()
];
}
$orderEntity = $order->saveOrder($cart, $session);
return $this->render('app/ecommerce/checkout_ok.html.twig', ['order' => $orderEntity, 'order_products' => $listProducts]);
} else {
return $this->redirectToRoute('checkout');
}
} catch (Error $e) {
return $this->render('app/ecommerce/checkout_error.html.twig', ['error' => $e->getMessage()]);
}
}
}