<?php
declare(strict_types=1);
namespace App\Controller\Front\Api\Cart;
use App\Application\Service\Cart\CartService;
use App\Application\Service\Cart\SummaryCartService;
use App\Application\Service\Session\SessionService;
use App\Entity\System\Customer;
use App\Factory\Front\Api\Cart\CartDetailsResponseFactory;
use App\Factory\Front\Api\Cart\CartServiceDetailsResponseFactory;
use App\Manager\System\CartManager;
use App\Service\Cart\CartService as NewCartService;
use App\Factory\Front\Api\Cart\ShippingCostResponseFactory;
use App\Manager\System\CartProductManager;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\SerializerInterface;
use function Sentry\captureException;
class CartController extends AbstractController
{
public function __construct(
private readonly CartProductManager $cartProductManager,
private readonly ShippingCostResponseFactory $shippingCostResponseFactory,
private readonly SessionService $sessionService,
private readonly NewCartService $newCartService,
private readonly SerializerInterface $serializer,
private readonly CartService $cartService,
private readonly SummaryCartService $summaryCartService,
private readonly CartManager $cartManager,
private readonly CartServiceDetailsResponseFactory $cartServiceDetailsResponseFactory,
private readonly CartDetailsResponseFactory $cartDetailsResponseFactory,
) {
}
/**
* @Route("/front/api/cart/products-count", name="front_api_cart_products_count", methods={"GET"})
*/
public function getProductsCount(): Response
{
$cartId = (int)$this->sessionService->get('id_cart');
try {
$cartProductsCount = $cartId === 0 ? 0 : $this->cartProductManager->getNumberProductsInCart($cartId);
} catch (NoResultException|NonUniqueResultException $exception) {
$cartProductsCount = 0;
}
return new Response(
\json_encode(['cartProductsCount' => $cartProductsCount]),
Response::HTTP_OK,
['content-type' => 'application/json']
);
}
/**
* @IsGranted("IS_AUTHENTICATED_FULLY")
*
* @Route("/front/api/cart/details", name="front_api_cart_details", methods={"GET"})
*/
public function getCartDetails(): JsonResponse
{
try {
/** @var Customer $customer */
$customer = $this->getUser();
if (empty($this->sessionService->get('id_cart'))) {
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
}
$cartId = (int)$this->sessionService->get('id_cart');
$cart = $this->cartManager->findOneById($cartId);
if (!$cart) {
return new JsonResponse('cart not found', Response::HTTP_NO_CONTENT);
}
$languageIsoCode = $this->sessionService->getLocale();
$summaryCart = $this->summaryCartService->getFromCustomerAndCart($customer, $cart, $languageIsoCode);
$cartProductsResponse = $this->cartDetailsResponseFactory->createBySummaryCart($summaryCart, $customer, $languageIsoCode);
return new JsonResponse($this->serializer->serialize($cartProductsResponse, JsonEncoder::FORMAT), Response::HTTP_OK, [], true);
} catch (\LogicException $LogicException) {
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (\Throwable $exception) {
captureException($exception);
return new JsonResponse($exception->getMessage(), Response::HTTP_BAD_REQUEST);
}
}
/**
* @IsGranted("IS_AUTHENTICATED_FULLY")
*
* @Route("/front/api/cart-services/details", name="front_api_cart_services_details", methods={"GET"})
*/
public function getCartServicesDetails(): JsonResponse
{
try {
/** @var Customer $customer */
$customer = $this->getUser();
$cartId = (int)$this->sessionService->get('id_cart_services');
if (empty($cartId)) {
throw new \RuntimeException('CartId not found');
}
$cart = $this->cartManager->findOneById($cartId);
if (!$cart || $cart->getCustomer()->getId() !== $customer->getId()) {
throw new \RuntimeException('cart not found');
}
$languageIsoCode = $this->sessionService->getLocale();
$summaryCart = $this->summaryCartService->getFromCustomerAndCart($customer, $cart, $languageIsoCode);
$cartProductsResponse = $this->cartServiceDetailsResponseFactory->createFromSummaryCart($summaryCart, $languageIsoCode, $customer);
return new JsonResponse($this->serializer->serialize($cartProductsResponse, JsonEncoder::FORMAT), Response::HTTP_OK, [], true);
} catch (\LogicException $LogicException) {
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
} catch (\Throwable $exception) {
captureException($exception);
return new JsonResponse($exception->getMessage(), Response::HTTP_BAD_REQUEST);
}
}
/**
* @IsGranted("IS_AUTHENTICATED_FULLY")
*
* @Route("/front/api/cart/update", name="front_api_cart_update", methods={"POST"})
*/
public function updateCart(Request $request): Response
{
try {
$cartRequest = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
$cartId = (int)$this->sessionService->get('id_cart');
$cartProducts = $this->newCartService->updateCart($cartId, $cartRequest);
return new JsonResponse($this->serializer->serialize($cartProducts, JsonEncoder::FORMAT), Response::HTTP_OK, [], true);
} catch (\Throwable $exception) {
captureException($exception);
return new JsonResponse('', Response::HTTP_BAD_REQUEST);
}
}
/**
* @IsGranted("IS_AUTHENTICATED_FULLY")
*
* @Route("/front/api/cart/shipping-costs", name="front_api_cart_shipping_costs", methods={"GET"})
*/
public function shippingCostsCart(Request $request): Response
{
try {
$isoCode = $request->get('isoCode');
$postalCode = $request->get('postalCode');
if (!$isoCode || !$postalCode) {
return new Response('IsoCode and PostalCode are required', Response::HTTP_BAD_REQUEST);
}
$cartId = (int)$this->sessionService->get('id_cart');
/** @var Customer $customer */
$customer = $this->getUser();
$languageIsoCode = $this->sessionService->getLocale();
$summaryCart = $this->cartService->getSummaryCartRequest(
$cartId,
$languageIsoCode,
$customer,
$isoCode,
$postalCode
);
$shippingCostsResponse = $this->shippingCostResponseFactory->createShippingCosts(
$summaryCart,
$isoCode,
$postalCode,
$languageIsoCode
);
return new JsonResponse($this->serializer->serialize($shippingCostsResponse->carrierDataResponse, JsonEncoder::FORMAT), Response::HTTP_OK, [], true);
} catch (\LogicException $LogicException) {
return new JsonResponse($LogicException->getMessage(), Response::HTTP_NO_CONTENT);
} catch (\Throwable $exception) {
captureException($exception);
return new JsonResponse($exception->getMessage(), Response::HTTP_BAD_REQUEST);
}
}
}