<?php
namespace App\Controller\Front;
use App\Entity\AttributValue;
use App\Entity\Cart;
use App\Entity\CartElement;
use App\Entity\Category;
use App\Entity\Creation;
use App\Entity\FeatureFamily;
use App\Entity\Model;
use App\Entity\ModelProductMenuMaker;
use App\Entity\Product;
use App\Entity\ProductPrice;
use App\Entity\User;
use App\Service\CartService;
use App\Service\CatalogService;
use App\Service\ModuleService;
use App\Service\ProductService;
use App\Service\QrCodeService;
use App\Service\Tools;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Routing\Annotation\Route;
/**
* Class CatalogController
* @package App\Controller\Front
* @Route(path="/catalog", name="catalog_", options={"expose"=true})
*/
class CatalogController extends AbstractController
{
public string $module;
private ModuleService $moduleService;
private CatalogService $catalogService;
private ProductService $productService;
private CartService $cartService;
private Tools $tools;
private EntityManagerInterface $em;
private QrCodeService $qrCodeService;
public function __construct(
ModuleService $moduleService,
CatalogService $catalogService,
ProductService $productService,
CartService $cartService,
Tools $tools,
EntityManagerInterface $em,
QrCodeService $qrCodeService,
) {
$this->module = 'catalog';
$this->moduleService = $moduleService;
$this->catalogService = $catalogService;
$this->productService = $productService;
$this->cartService = $cartService;
$this->tools = $tools;
$this->em = $em;
$this->qrCodeService = $qrCodeService;
}
/**
* @return Response
* @Route("/cannot/order", name="cannot_order")
*/
public function cannotOrder(): Response
{
return $this->redirectToRoute('app_index');
// return $this->render('front/catalog/cannotOrder.html.twig');
}
/**
* @param User|null $customer
* @return Response
* @Route("/{customer}", name="index")
*/
public function index(User $customer = null): Response
{
if (!$this->moduleService->access($this->module) and !$this->moduleService->access('catalog_wallet', 'command')) {
return $this->redirectToRoute('app_index');
}
/** @var User $user */
$user = $this->getUser();
if (!$user->getCanOrder()) {
return $this->redirectToRoute('catalog_cannot_order');
}
if (!is_null($customer)) {
if (!$customer->getCanOrder()) {
return $this->redirectToRoute('catalog_cannot_order');
}
}
$categoriesTop = $this->em->getRepository(Category::class)->getRootNodes('position');
if ($customer) {
$session = new Session();
$session->set('customer', $customer->getId());
}
return $this->render('front/catalog/index.html.twig', [
'categories' => $categoriesTop,
]);
}
/**
* @param Category $category
* @return Response
* @Route("/category/{category}", name="category", requirements={"category"="\d+"})
*/
public function category(Category $category): Response
{
if (!$this->catalogService->isCategoryValid($category)) {
return $this->redirectToRoute('app_index');
}
/** @var User $user */
$user = $this->getUser();
if (!$user->getCanOrder()) {
return $this->redirectToRoute('catalog_cannot_order');
}
$marketingZone = $this->catalogService->getMarketingZone($category);
//Si aucune zone marketing, on cherche une zone sur la catégorie parent
if (!$marketingZone && $category->getParent()) {
$marketingZone = $this->catalogService->getMarketingZone($category->getParent());
}
return $this->render('front/catalog/category.html.twig', [
'category' => $category,
'marketingZone' => $marketingZone,
]);
}
/**
* @param Product $product
* @return RedirectResponse|Response
* @Route("/product/{product}", name="product", requirements={"product"="\d+"})
*/
public function product(Product $product): RedirectResponse|Response
{
if (!$this->productService->isCommandable($product)) {
return $this->redirectToRoute('app_index');
}
/** @var User $user */
$user = $this->getUser();
if (!$user->getCanOrder()) {
return $this->redirectToRoute('catalog_cannot_order');
}
$session = new Session();
return $this->render('front/catalog/product.html.twig', [
'product' => $product,
'customerSession' => $session->get('customer'),
'economicalTurnover' => $this->tools->getSettingByName('ECONOMICAL_TURNOVER')
]);
}
/**
* @param Product $product
* @param Request $request
* @return JsonResponse
* @throws Exception
* @Route("/product/{product}/feature-values", name="product_feature_values", requirements={"product"="\d+"}, options={"expose"=true})
*/
public function productFeatureValues(Product $product, Request $request): JsonResponse
{
if (!$this->productService->isCommandable($product)) {
return new JsonResponse([
'success' => false,
'url' => $this->generateUrl('app_index'),
]);
}
$productFeatureValues = $this->productService->getProductFeatureValuesByProduct($product);
/** @var Model $model */
$model = $this->em->getRepository(Model::class)->find($request->request->get('model'));
if (!is_null($model)) {
$modelProductFeatureValues = [];
/** @var ModelProductMenuMaker $modelProductMenuMaker */
foreach ($model->getModelProductMenuMakers() as $modelProductMenuMaker) {
if ($modelProductMenuMaker->getProductMenuMaker()->getProduct() === $product) {
if ($modelProductMenuMaker->isProductMenuMakerHaveFile() or $modelProductMenuMaker->isEquivalentProductMenuMakerHaveFile()) {
$modelProductFeatureValues[] = $modelProductMenuMaker->getProductMenuMaker()->productFeatureValueFormat()->getPosition() . '~' . $modelProductMenuMaker->getProductMenuMaker()->productFeatureValueFormat()->getId();
}
}
}
foreach ($productFeatureValues as $key => $productFeatureValue) {
if (!in_array($key, $modelProductFeatureValues)) {
unset($productFeatureValues[$key]);
}
}
}
return new JsonResponse([
'success' => true,
'productFeatureValues' => $productFeatureValues,
]);
}
/**
* @param Product $product
* @param Request $request
* @return JsonResponse
* @Route("/product/{product}/prices", name="product_prices", requirements={"product"="\d+"}, options={"expose"=true})
* @throws Exception
*/
public function productPrices(Product $product, Request $request): JsonResponse
{
if (!$this->productService->isCommandable($product)) {
return new JsonResponse([
'success' => false,
'url' => $this->generateUrl('app_index'),
]);
}
$productFeatureValues = (!is_null($request->request->get('productFeatureValues')) ? $request->request->get('productFeatureValues') : []);
$attributValues = (!is_null($request->request->get('attributValues')) ? $request->request->get('attributValues') : []);
$isFormatVariable = (!is_null($request->request->get('isFormatVariable')) ? $request->request->get('isFormatVariable') : false);
$width = ($request->request->get('width') ? $request->request->get('width') : null);
$height = ($request->request->get('height') ? $request->request->get('height') : null);
return new JsonResponse([
'success' => true,
'template' => $this->renderView('front/catalog/product_price.html.twig', [
'quantities' => $this->productService->calculPriceByProductPrices($product, $productFeatureValues, $attributValues, $isFormatVariable, $width, $height),
]),
]);
}
/**
* @param Product $product
* @param User $customer
* @param Request $request
* @return JsonResponse
* @throws Exception|TransportExceptionInterface
* @Route("/product/{product}/add-cart/{customer}", name="product_add_cart", requirements={"product"="\d+", "customer"="\d+"})
*/
public function addCart(Product $product, User $customer, Request $request): JsonResponse
{
if (!$this->productService->isCommandable($product)) {
return new JsonResponse([
'success' => false,
'url' => $this->generateUrl('app_index'),
]);
}
$customerEmail = $request->request->get('customerEmail');
if (!empty($customerEmail)) {
$customer->setEmail($customerEmail);
if (is_null($customer->getQrCodeMizogoo())) {
$res = $this->qrCodeService->mizogooQrCode($customer);
if (!$res['success']) {
return new JsonResponse($res);
}
}
$this->em->persist($customer);
$this->em->flush();
}
$model = $request->request->get('model');
if (!is_null($model)) {
/** @var Model $model */
$model = $this->em->getRepository(Model::class)->find($model);
}
$attributValues = (!is_null($request->request->get('attributValues')) ? $request->request->get('attributValues') : []);
$quantity = (!is_null($request->request->get('quantity')) ? $request->request->get('quantity') : 1);
$productPriceId = (!is_null($request->request->get('productPriceId')) ? $request->request->get('productPriceId') : null);
$width = $request->request->get('width');
$height = $request->request->get('height');
/** @var ProductPrice $productPrice */
$productPrice = $this->em->getRepository(ProductPrice::class)->findOneBy([
'id' => $productPriceId
]);
if (!is_null($productPrice)) {
/** @var Cart $cart */
$cart = $customer->getCurrentCart();
if (!$cart) {
$cart = $this->cartService->create($customer);
}
$cartElement = new CartElement();
$cartElement->setCart($cart);
$cartElement->setProduct($product);
$cartElement->setProductPrice($productPrice);
$cartElement->setQuantity($quantity);
if ($product->isCustomizable()) {
$creation = new Creation();
$creation->setUser($customer);
$creation->setProduct($product);
$creation->setModel($model);
if ($width) {
$creation->setWidth($width);
}
if ($height) {
$creation->setHeight($height);
}
foreach ($productPrice->getProductFeatureValues() as $productFeatureValue) {
if ($productFeatureValue->getProductFeature()->getFeature()->getFeatureFamily()->getConstName() == FeatureFamily::CUSTOMIZABLE) {
$creation->addProductFeatureValue($productFeatureValue);
}
}
$this->em->persist($creation);
$cartElement->setCreation($creation);
} elseif ($product->isClassic()) {
$creation = new Creation();
$creation->setUser($customer);
$creation->setProduct($product);
foreach ($productPrice->getProductFeatureValues() as $productFeatureValue) {
if ($productFeatureValue->getProductFeature()->getFeature()->getFeatureFamily()->getConstName() == FeatureFamily::CUSTOMIZABLE) {
$creation->addProductFeatureValue($productFeatureValue);
}
}
$this->em->persist($creation);
$cartElement->setCreation($creation);
}
if ($attributValues) {
foreach ($attributValues as $value) {
/** @var AttributValue $attributValue */
$attributValue = $this->em->getRepository(AttributValue::class)->find($value);
if (!is_null($attributValue)) {
$cartElement->addAttributValue($attributValue);
}
}
}
$cart->addCartElement($cartElement);
$this->em->persist($cartElement);
$this->em->flush();
$url = $this->generateUrl('cart_index', ['customer' => $customer->getId()]);
if ($cartElement->getCreation()) {
if ($product->getReference() === Product::PRODUCT_REF_SF or $product->getReference() === Product::PRODUCT_REF_MF) {
$url = $this->generateUrl('creation_classic_index', ['creation' => $cartElement->getCreation()->getId()]);
} else {
if ($product->isOldBuilder()) {
$url = $this->generateUrl('creation_menumaker_menumaker', ['creation' => $cartElement->getCreation()->getId(), 'cartElement' => $cartElement->getId()]);
} else {
$url = $this->generateUrl('menubuilder_index', ['creation' => $cartElement->getCreation()->getId()]);
}
}
}
return new JsonResponse([
'success' => true,
'url' => $url,
]);
}
return new JsonResponse([
'success' => false,
]);
}
}