<?php
namespace App\Controller;
use App\Entity\Article;
use App\Entity\DeliveryCountry;
use App\Entity\DeliveryMethod;
use App\Exception\CartException;
use App\Form\Handler\CartHandler;
use App\Form\Type\CartType;
use App\Helper\VeltisControllerTrait;
use App\Repository\DeliveryCountryRepository;
use App\Repository\DeliveryMethodRepository;
use App\Repository\LanguageRepository;
use App\Repository\ProductRepository;
use App\Services\CartService;
use App\Services\FacebookApiConversion;
use App\Twig\AppExtension;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use FOS\RestBundle\Controller\Annotations as Rest;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\BrowserKit\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\View\View;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\Translation\TranslatorInterface;
class CartController extends AbstractController
{
use VeltisControllerTrait;
/**
* @Route("/cart", name="cart")
*/
public function cartAction(Request $request, CartService $cartService, ProductRepository $productRepository, LanguageRepository $languageRepository, DeliveryMethodRepository $deliveryMethodRepository, CartHandler $cartHandler)
{
$language = $this->resolveLanguage($request->getLocale());
$cartService->cartRecalculate($language);
$cart = $cartService->getOrCreateCart();
$showNotification = 0;
if ($cart->getRemovedProductsNotification()) {
$showNotification = 1;
$cart->setRemovedProductsNotification(0);
$this->em()->persist($cart);
$this->em()->flush();
}
$cartService->removeInvisible($cart);
$form = $this->createForm(CartType::class, $cart);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$cartHandler->handle($cart);
//return $this->redirectToRoute('cart');
header("Location: /cart");
exit();
}
}
$cs = $cartService->getCrossSellingProducts($cartService->getCart());
$ids = [];
foreach ($cs as $r) {
$ids[] = $r->getId();
}
$search = [];
$search['locale'] = $request->getLocale();
if (count($ids)) {
$queryCrossSelling = $productRepository->getForCrossSelling($ids, $search)->getQuery()->getResult();
} else {
$queryCrossSelling = [];
}
$paymentId = null;
if ($cartService->getCart() and $cartService->getCart()->getPaymentMethod()) {
$paymentId = $cartService->getCart()->getPaymentMethod()->getId();
}
$deliveryId = null;
if ($cartService->getCart() and $cartService->getCart()->getDeliveryMethod()) {
$deliveryId = $cartService->getCart()->getDeliveryMethod()->getId();
}
$sumInfo = $cartService->ajaxCalculateSum($deliveryId, $paymentId);
$shoppingArticle = $this->em()->getRepository(Article::class)->find(Article::getShoppingArticleId($request->getLocale()));
$view = $this->render('frontend/cart/cart.html.twig', [
'form' => $form->createView(),
'shoppingArticle' => $shoppingArticle,
'countries' => $languageRepository->getAll($cartService->getLocale())->getQuery()->getResult(),
'defaultCountry' => [],
'cartSpecialDeliveryMethods' => $cartService->getSpecialDeliveryMethodsIds($cartService->getCart()),
'cart' => $cartService->getCart(),
'language' => $language,
'sumInfo' => $sumInfo,
'showNotification' => $showNotification,
'crossSelling' => $queryCrossSelling,
'cartProducts' => $cartService->getCartProducts(),
'locale' => $cartService->getLocale(),
'currency' => $this->get('session')->get('currency'),
'deliveryMethods' => $deliveryMethodRepository->getDeliveryMethodsForLanguage($language)->getQuery()->getResult()
]);
$view->headers->set('Cache-Control', 'no-cache, no-store, must-revalidate');
$view->headers->set('Pragma', 'no-cache');
$view->headers->set('Expires', '0');
return $view;
}
/**
* When user change delviery country -> reload delivery methods
* @Route("/cart/load-delivery-methods", name="load_delivery_methods")
*/
public function ajaxDeliveryMethodsAction(Request $request, CartService $cartService, DeliveryMethodRepository $deliveryMethodRepository) {
$id = $request->request->get('id');
/** @var $deliveryCountry DeliveryCountry */
$deliveryCountry = $this->get(DeliveryCountryRepository::class)->getRepository()->find($id);
return $this->render('frontend/cart/_deliveryMethods.html.twig', [
'defaultCountry' => $deliveryCountry,
'locale' => $cartService->getLocale(),
'currency' => $this->get('session')->get('currency'),
'deliveryMethods' => $deliveryMethodRepository->getDeliveryMethodsForCountry($deliveryCountry)->getQuery()->getResult()
]);
}
/**
* When user change delivery method - load associated payment methods
* @Route("/cart/load-payment-methods", name="load_payment_methods")
*/
public function ajaxPaymentMethodsAction(Request $request, CartService $cartService, DeliveryMethodRepository $deliveryMethodRepository) {
$id = $request->request->get('id');
/** @var $deliveryMethod DeliveryMethod */
$deliveryMethod = $deliveryMethodRepository->getRepository()->find($id);
$payments = $deliveryMethod->getPaymentMethods();
return $this->render('frontend/cart/_paymentMethods.html.twig', [
'locale' => $cartService->getLocale(),
'currency' => $this->get('session')->get('currency'),
'payments' => $payments
]);
}
/**
* When user change delivery method or payment method - load dynamically calculated sum
* @Route("/cart/calculate-sum", name="ajax_calculate_sum")
*/
public function ajaxDynamicCalculateSumAction(Request $request, CartService $cartService, AppExtension $appExtension) {
$deliveryId = $request->request->get('deliveryId');
$paymentId = $request->request->get('paymentId');
$sum = $cartService->ajaxCalculateSum($deliveryId, $paymentId);
$formatSum = $appExtension->formatPrice($sum['sum'], $cartService->getCurrency());
$formatSumWithRebate = $appExtension->formatPrice($sum['sumWithRebate'], $cartService->getCurrency());
$formatSavings = $appExtension->formatPrice($sum['sumWithRebate'] - $sum['sum'], $cartService->getCurrency());
return new JsonResponse(['savings'=>$formatSavings, 'sum'=>$formatSum, 'sumWithRebate'=>$formatSumWithRebate]);
}
/**
* Next click button Handler - go to register or login page
* @Route("/cart/checkout-handler", name="ajax_save_cart")
*/
public function ajaxSaveCartAction(Request $request, CartService $cartService) {
$cart = $cartService->getCart();
$deliveryId = $request->request->get('deliveryId');
$paymentId = $request->request->get('paymentId');
$cartService->prepareToCheckout($deliveryId, $paymentId);
return new JsonResponse([]);
}
/**
* When user click discard rebate code in the cart
* @Route("/cart/discard-rebate-code", name="discard_cart_rebate_code")
*/
public function discardRebateCode(Request $request, CartService $cartService) {
$cartService->discardRebateCode();
return $this->redirectToRoute('cart');
}
/**
* @Route("/cart/add", name="add_to_cart")
*/
public function addToCartAction(Request $request, LoggerInterface $logger, CartService $cartService, TranslatorInterface $translator, FacebookApiConversion $facebookApiConversion): JsonResponse {
$product = $cartService->getProductEntity($request->request->get('product_id'));
$quantity = $request->request->get('quantity');
if (!is_numeric($quantity)) {
$quantity = 1;
}
if ($cartService->isMaxQuantityExceeded($product, $quantity)) {
return new JsonResponse(['message'=>$translator->trans('max_quantity_exceeded_message', ['%count%'=>$product->getMaxQuantity()], 'store', $request->getLocale()), 'error'=>1]);
}
if ($request->getLocale() != 'pl') {
try {
$facebookApiConversion->createFbEvent('AddToCart');
} catch (\Exception $exception) {
//
}
}
try {
$cartService->addToCart($request);
} catch (CartException $e) {
$logger->critical($e->getMessage());
return new JsonResponse(['message'=>$translator->trans('session_invalidated', [], 'store', $request->getLocale()), 'error'=>1]);
}
return new JsonResponse(['message'=>'ok', 'error'=>0, 'result'=>$cartService->isMaxQuantityExceeded($product, $quantity)]);
}
private function generateSessionCode() {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = '';
for ($i = 0; $i < 36; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
return $randomString;
}
/**
* @Route("/cart/remove-element", name="remove_from_cart")
*/
public function removeFromCartAction(Request $request, CartService $cartService)
{
$cartService->removeFromCart($request);
return new JsonResponse(['message'=>'ok']);
}
/**
* @Route("/cart/update-quantity-cart", name="update_quantity_cart")
*/
public function updateQuantityAction(Request $request, CartService $cartService, TranslatorInterface $translator)
{
$product = $cartService->getProductEntity($request->request->get('product_id'));
$quantity = $request->request->get('quantity');
if (!is_numeric($quantity)) {
$quantity = 1;
}
if ($quantity <= 0) {
return new JsonResponse(['message'=>$translator->trans('invalid_number', [], 'store', $request->getLocale()), 'error'=>1]);
}
if ($cartService->isMaxQuantityExceeded($product, $quantity)) {
return new JsonResponse(['message'=>$translator->trans('max_quantity_exceeded_message', ['%count%'=>$product->getMaxQuantity()], 'store', $request->getLocale()), 'error'=>1]);
}
if ($cartService->isSubProductInCart($request)) {
return new JsonResponse(['message'=>$translator->trans('max_quantity_exceeded_message', ['%count%'=>1], 'store', $request->getLocale()), 'error'=>1]);
}
$cartService->updateQuantityCart($request);
return new JsonResponse(['message'=>'ok', 'error'=>0, 'result'=>$cartService->isMaxQuantityExceeded($product, $quantity)]);
}
}