<?php
namespace App\Controller\Frontend;
use App\Business\Cart\Calculator\CartTotalCalculatorInterface;
use App\Business\Cart\CartConstants;
use App\Business\Cart\Mapper\CartAreaResponseMapperInterface;
use App\Business\Cart\Session\CartSessionHandlerInterface;
use App\Business\Cart\Transfer\CartAreaTransfer;
use App\Entity\CustomerAdvertisingArea;
use App\Form\Frontend\CustomerAdvertisingAreaSelectionType;
use App\Service\Utils\AreaContributionPriceCalculatorInterface;
use App\Service\Utils\ToStringService;
use Doctrine\ORM\EntityManagerInterface;
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\Contracts\Translation\TranslatorInterface;
class CartController extends AbstractController
{
private AreaContributionPriceCalculatorInterface $contributionPriceCalculator;
private CartSessionHandlerInterface $cartSessionHandler;
private EntityManagerInterface $entityManager;
private CartAreaResponseMapperInterface $cartAreaResponseMapper;
private CartTotalCalculatorInterface $cartTotalCalculator;
/**
* @param EntityManagerInterface $entityManager
* @param CartSessionHandlerInterface $cartSessionHandler
* @param AreaContributionPriceCalculatorInterface $contributionPriceCalculator
* @param CartAreaResponseMapperInterface $cartAreaResponseMapper
* @param CartTotalCalculatorInterface $cartTotalCalculator
*/
public function __construct(
EntityManagerInterface $entityManager,
CartSessionHandlerInterface $cartSessionHandler,
AreaContributionPriceCalculatorInterface $contributionPriceCalculator,
CartAreaResponseMapperInterface $cartAreaResponseMapper,
CartTotalCalculatorInterface $cartTotalCalculator
) {
$this->contributionPriceCalculator = $contributionPriceCalculator;
$this->cartSessionHandler = $cartSessionHandler;
$this->entityManager = $entityManager;
$this->cartAreaResponseMapper = $cartAreaResponseMapper;
$this->cartTotalCalculator = $cartTotalCalculator;
}
/**
* @return Response
*/
#[Route('/cart', name: 'app_frontend_cart')]
public function cart(): Response
{
$areas = [];
/** @var CartAreaTransfer $item */
foreach ($this->cartSessionHandler->getItems() as $item) {
$area = $this->entityManager->getRepository(CustomerAdvertisingArea::class)
->findOneBy(['uuid' => $item->getUuidCustomerAdvertisingArea()]);
$areas[] = $this->cartAreaResponseMapper->mapFromEntity($area, $item->isWithinSetupPrice());
}
return $this->render('frontend/cart/cart.html.twig', [
'areas' => $areas,
'cartTotal' => ToStringService::toString($this->cartTotalCalculator->calculate()),
]);
}
/**
* @param TranslatorInterface $translator
* @param Request $request
* @param string $uuidArea
*
* @return Response
*/
#[Route('/cart/modal/add/{uuidArea}', name: 'app_frontend_cart_modal_add')]
public function addToCartModal(
TranslatorInterface $translator,
Request $request,
string $uuidArea
): Response {
$customerAdvertisingArea = $this->entityManager
->getRepository(CustomerAdvertisingArea::class)
->findOneBy(['uuid' => $uuidArea]);
$form = $this->createForm(CustomerAdvertisingAreaSelectionType::class, $customerAdvertisingArea)
->handleRequest($request);
/* @todo handle form submit */
$withinSetup = $form->get(CustomerAdvertisingAreaSelectionType::FIELD_WITHIN_SETUP_PRICE)->getData();
$pricePerMonth = $this->contributionPriceCalculator->calculateByCustomerConfiguration($customerAdvertisingArea);
$settings = $customerAdvertisingArea->getSettings();
$params = [
'uuid' => $customerAdvertisingArea->getUuid(),
'description' => $customerAdvertisingArea->getSettings()->getDescription(),
'unitWidth' => $customerAdvertisingArea->getSettings()->getUnitWidth(),
'unitHeight' => $customerAdvertisingArea->getSettings()->getUnitHeight(),
'priceUnitYear' => sprintf(
'%s %s',
number_format($pricePerMonth * 12, 2, ',', '.'),
$translator->trans('app.currency_sign')
),
'setupPriceUnit' => sprintf(
'%s %s',
number_format($settings->getSetupPriceUnit(), 2, ',', '.'),
$translator->trans('app.currency_sign')
),
'minDuration' => $settings->getMinDuration(),
'priceDuration' => sprintf(
'%s %s',
number_format($pricePerMonth * $settings->getMinDuration(), 2, ',', '.'),
$translator->trans('app.currency_sign')
),
];
$total = ($withinSetup)
? $pricePerMonth * $settings->getMinDuration() + $settings->getSetupPriceUnit()
: $pricePerMonth * $settings->getMinDuration();
$params = array_merge($params, [
'total' => sprintf(
'%s %s',
number_format($total, 2, ',', '.'),
$translator->trans('app.currency_sign')
),
]);
return $this->render('frontend/cart/modal/add-to-cart__modal-body.twig', array_merge($params, [
'form' => $form->createView(),
]));
}
/**
* @param Request $request
*
* @return Response
*/
#[Route('/cart/add', name: 'app_frontend_cart_add_item')]
public function addToCart(Request $request): Response
{
$uuidCustomerAdvertisingArea = $request->get(CartConstants::UUID_AREA);
$withinSetupPrice = $request->get(CartConstants::WITHIN_SETUP) === 'true';
$cartAreaTransfer = (new CartAreaTransfer())
->setUuidCustomerAdvertisingArea($uuidCustomerAdvertisingArea)
->setWithinSetupPrice($withinSetupPrice);
$this->cartSessionHandler->addToCart($cartAreaTransfer);
return new JsonResponse(array_merge([
'cartTotal' => ToStringService::toString($this->cartTotalCalculator->calculate())
], $this->cartAreaResponseMapper->mapFromTransfer($cartAreaTransfer)));
}
/**
* @param string $uuidCustomerAdvertisingArea
*
* @return Response
*/
#[Route('/cart/remove/{uuidCustomerAdvertisingArea}', name: 'app_frontend_cart_remove_item')]
public function removeFromCart(string $uuidCustomerAdvertisingArea): Response
{
$this->cartSessionHandler->removeFromCart($uuidCustomerAdvertisingArea);
return new JsonResponse([
'uuid' => $uuidCustomerAdvertisingArea,
'cartTotal' => ToStringService::toString($this->cartTotalCalculator->calculate())
]);
}
/**
* @param EntityManagerInterface $entityManager
*
* @return Response
*/
#[Route('/cart/shopping-cart', name: 'app_frontend_cart_shopping_cart')]
public function shoppingCart(EntityManagerInterface $entityManager): Response
{
$areas = [];
/** @var CartAreaTransfer $item */
foreach ($this->cartSessionHandler->getItems() as $item) {
$area = $entityManager->getRepository(CustomerAdvertisingArea::class)
->findOneBy(['uuid' => $item->getUuidCustomerAdvertisingArea()]);
$areas[] = $this->cartAreaResponseMapper->mapFromEntity($area, $item->isWithinSetupPrice());
}
return new JsonResponse([
'cartTotal' => ToStringService::toString($this->cartTotalCalculator->calculate()),
'areas' => $areas
]);
}
/**
* @param Request $request
*
* @return Response
*/
#[Route('/cart/toggle-area-production-and-setup', name: 'app_frontend_cart_toogle-production-and-setup')]
public function toggleAreaProductionAndSetup(Request $request): Response
{
$areaTransfer = $this->cartSessionHandler->getItem($request->get(CartConstants::UUID_AREA));
if ($areaTransfer === null) {
return new JsonResponse(false);
}
$this->cartSessionHandler->toggleAreaProductionAndSetup($areaTransfer->getUuidCustomerAdvertisingArea());
$areaTransfer = $this->cartSessionHandler->getItem($request->get(CartConstants::UUID_AREA));
return new JsonResponse([
'cartTotal' => ToStringService::toString($this->cartTotalCalculator->calculate()),
'area' => $this->cartAreaResponseMapper->mapFromTransfer($areaTransfer),
]);
}
/**
* @return Response
*/
#[Route('/cart/refresh', name: 'app_frontend_cart_refresh-cart-total-and-item-count')]
public function refreshCartTotalAndItemCount(): Response
{
return new JsonResponse([
'cartTotal' => ToStringService::toString($this->cartTotalCalculator->calculate()),
'areaCount' => count($this->cartSessionHandler->getItems()),
]);
}
}