<?php
declare(strict_types=1);
namespace App\Controller\Shop;
use App\Entity\Channel\ChannelPricing;
use App\Entity\Order\Order;
use App\Entity\Product\ProductVariant;
use App\Entity\Product\SimpleProductOption;
use App\Entity\Product\SimpleProductOptionValue;
use App\Provider\PriceTTCProvider;
use Sylius\Bundle\OrderBundle\Controller\AddToCartCommandInterface;
use Sylius\Bundle\OrderBundle\Controller\OrderItemController;
use Sylius\Component\Order\CartActions;
use Sylius\Component\Order\Model\OrderItemInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class AddItemToCartController extends OrderItemController
{
public function addAction(Request $request): Response
{
/** @var Order $cart */
$cart = $this->getCurrentCart();
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, CartActions::ADD);
/** @var OrderItemInterface $orderItem */
$orderItem = $this->newResourceFactory->create($configuration, $this->factory);
$this->getQuantityModifier()->modify($orderItem, 1);
$form = $this->getFormFactory()->create(
$configuration->getFormType(),
$this->createAddToCartCommand($cart, $orderItem),
$configuration->getFormOptions()
);
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
$moneyFormatter = $this->container->get('sylius.money_formatter');
// récupérer toutes les options possibles
$em = $this->getDoctrine()->getManager();
$simpleProductOptions = $em->getRepository(SimpleProductOption::class)->findAll();
$simpleProductOptionsCodes = [];
/** @var SimpleProductOption $simpleProductOption */
foreach ($simpleProductOptions as $simpleProductOption) {
$simpleProductOptionsCodes[] = $simpleProductOption->getCode();
}
// parcourir $request->request->all() pour voir si des éléments correspondent aux options
// si oui, on ajoute à l'orderItem l'option et l'option value
$orderItemOptions = [];
foreach ($request->request->all() as $key => $value) {
if (in_array($key, $simpleProductOptionsCodes)) {
/** @var SimpleProductOptionValue $simpleProductOptionValue */
$simpleProductOptionValue = $em->getRepository(SimpleProductOptionValue::class)->findOneBy(['code' => $value]);
if ($simpleProductOptionValue) {
$orderItemOptions[$key]['code'] = $simpleProductOptionValue->getCode();
$orderItemOptions[$key]['price'] = $simpleProductOptionValue->getPrice();
$orderItemOptions[$key]['name'] = $simpleProductOptionValue->getTranslation($cart->getLocaleCode())->getName();
}
}
}
/** @var AddToCartCommandInterface $addToCartCommand */
$addToCartCommand = $form->getData();
/** @var ProductVariant $variant */
$variant = $addToCartCommand->getCartItem()->getVariant();
/** @var ChannelPricing $pricing */
$price = $variant->getChannelPricingForChannel($cart->getChannel())->getPrice();
$totalPrice = $price;
$htmlSimpleProductOptions = '';
$installation = false;
if (count($orderItemOptions) > 0) {
foreach ($orderItemOptions as $orderItemOption => $orderItemOptionValue) {
if($orderItemOption === "installation" && $orderItemOptionValue['code'] !== "no_installation" ){
$installation = true;
}
$totalPrice += $orderItemOptionValue['price'];
$priceOptionConvert = $moneyFormatter->format($orderItemOptionValue['price'], $cart->getCurrencyCode(), $cart->getLocaleCode());
$htmlSimpleProductOptions .= '<div>
<small><strong class="visible-devis">'.$orderItemOptionValue['code'] .' : </strong>'. $priceOptionConvert .'</small>
</div>';
}
}
$addToCartCommand->getCartItem()->setImmutable(true);
$addToCartCommand->getCartItem()->setSimpleProductOptions($orderItemOptions);
$addToCartCommand->getCartItem()->setUnitPrice($totalPrice);
$errors = $this->getCartItemErrors($addToCartCommand->getCartItem());
if (0 < count($errors)) {
$form = $this->getAddToCartFormWithErrors($errors, $form);
return $this->handleBadAjaxRequestView($configuration, $form);
}
$event = $this->eventDispatcher->dispatchPreEvent(CartActions::ADD, $configuration, $orderItem);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
}
$this->getOrderModifier()->addToOrder($addToCartCommand->getCart(), $addToCartCommand->getCartItem());
$source_path = '//placehold.it/400x300';
if($variant->getImages()->first() != false) {
$source_path = $variant->getImages()->first()->getPath();
}
else {
if($variant->getProduct()->getImages()->first() != false) {
$source_path = $variant->getProduct()->getImages()->first()->getPath();
}
}
$cacheManager = $this->container->get('liip_imagine.cache.manager');
$path = $cacheManager->getBrowserPath(parse_url($source_path, PHP_URL_PATH), 'sylius_shop_product_large_thumbnail', [], null);
$htmlOptions = '';
foreach ($variant->getOptionValues() as $optionValue) {
$htmlOptions .= '<div>
<small><strong class="visible-devis">'.$optionValue->getName() .' : </strong>'. $optionValue->getValue() .'</small>
</div>';
}
$quantityAdd = $addToCartCommand->getCartItem()->getQuantity();
if ($variant->getName() !== null) {
$name = $variant->getName();
}
else {
$name = $variant->getProduct()->getName();
}
//add tva
/** @var PriceTTCProvider $priceTTCProvider */
$priceTTCProvider = $this->container->get('app.provider.price_ttc_provider');
$totalPrice = $priceTTCProvider->getPriceTTCFromVariant($variant, $totalPrice, $installation);
$priceConvert = $moneyFormatter->format((int)$totalPrice, $cart->getCurrencyCode(), $cart->getLocaleCode());
//partie datalayer
$gtmEventListener = $this->container->get('app.google_tag_manager.listener.event');
$datalayer = $gtmEventListener->addToCart($orderItem->getProduct());
$responseJson = [
'variantName' => $name,
'source_path' => $path,
'options' => $htmlOptions,
'quantity' => $quantityAdd,
'simpleProductOptions' => $htmlSimpleProductOptions,
'price' => $priceConvert,
'dataLayer' => $datalayer
];
$cartManager = $this->getCartManager();
$cartManager->persist($cart);
$cartManager->flush();
$resourceControllerEvent = $this->eventDispatcher->dispatchPostEvent(CartActions::ADD, $configuration, $orderItem);
if ($resourceControllerEvent->hasResponse()) {
return $resourceControllerEvent->getResponse();
}
return new Response(json_encode($responseJson));
}
if (!$configuration->isHtmlRequest()) {
return $this->handleBadAjaxRequestView($configuration, $form);
}
return $this->render(
$configuration->getTemplate(CartActions::ADD . '.html'),
[
'configuration' => $configuration,
$this->metadata->getName() => $orderItem,
'form' => $form->createView(),
]
);
}
}