<?php
namespace App\Controller;
use App\Entity\Delivery;
use App\Entity\Vinyl;
use App\Repository\PromoteRepository;
use App\Services\TaxService;
use Psr\Log\LoggerInterface;
use Stripe\Stripe;
use App\Entity\Uid;
use App\Entity\Order;
use Twig\Environment;
use App\Entity\Detail;
use DateTimeImmutable;
use App\Entity\Invoice;
use App\Entity\Product;
use App\Repository\DeliveryRepository;
use App\Model\Address;
use App\Repository\ParamsRepository;
use App\Repository\LivreurRepository;
use App\Repository\ProductRepository;
use App\Repository\LivraisonRepository;
use App\Repository\OrderRepository;
use App\Services\CartService;
use App\Services\ShippingService;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* @Security("is_granted('ROLE_USER')")
*/
class CartController extends AbstractController
{
private $stripePublicKey;
private $stripeSecretKey;
private $twig;
private $livraisonRepository;
private $productRepository;
private $deliveryRepository;
private $logger;
private $session;
private $translator;
private $taxService;
public function __construct(
LivraisonRepository $livraisonRepository,
ProductRepository $productRepository,
DeliveryRepository $deliveryRepository,
Environment $twig,
LoggerInterface $logger,
SessionInterface $session,
TranslatorInterface $translator,
TaxService $taxService
) {
if ($_ENV['APP_ENV'] === 'dev') {
$this->stripePublicKey = $_ENV['STRIPE_PK_TEST'];
$this->stripeSecretKey = $_ENV['STRIPE_SK_TEST'];
}
else {
$this->stripePublicKey = $_ENV['STRIPE_PK_PROD'];
$this->stripeSecretKey = $_ENV['STRIPE_SK_PROD'];
}
$this->twig = $twig;
$this->livraisonRepository = $livraisonRepository;
$this->productRepository = $productRepository;
$this->deliveryRepository = $deliveryRepository;
$this->logger = $logger;
$this->session = $session;
$this->translator = $translator;
$this->taxService = $taxService;
}
/**
* @Route("/panier", name="cart_index")
*/
public function index(
SessionInterface $session,
CartService $cartService,
LivreurRepository $livreurRepository,
ParamsRepository $paramsRepository,
PromoteRepository $promoteRepository,
ShippingService $shippingService,
Request $request
): Response
{
/** @var Uid $customer */
$customer = $this->getUser();
$cart = $customer->getCart();
$cartService->init($cart);
$shippingService->setCart($cart);
$shippingAddress = $session->get('shippingAddress', new Address());
$selectedDelivery = $session->get('selectedDelivery', null);
/** Vérification de la disponibilité de chaque produits */
if ($cartService->checkOutOfStockProducts() > 0) {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.out_of_stock_removed'));
return $this->redirectToRoute('cart_index');
}
$deliveryPrices = $shippingService->getDeliveryPrices($cartService);
/** Selection de la livraison */
if ($request->request->get('livraison') !== null) {
$shippingAddress = null;
$deliveryId = $request->request->get('livraison');
$selectedDelivery = $deliveryId === "retrait" || $deliveryId === "aside" ?
$deliveryId : $this->deliveryRepository->find($deliveryId);
/** La Poste */
if ($selectedDelivery instanceof Delivery && $selectedDelivery->getLivreur()->getName() === "la poste") {
$shippingAddress = new Address();
$shippingAddress->recipient = $customer->getFirstname() . ' ' . $customer->getLastname();
$shippingAddress->addressLine1 = $customer->getAddress()->getAddress();
$shippingAddress->complement = $customer->getAddress()->getComplement();
$shippingAddress->postalCode = $customer->getAddress()->getPostalCode();
$shippingAddress->city = $customer->getAddress()->getCity();
$shippingAddress->country = $customer->getAddress()->getCountry();
}
$session->set('shippingAddress', $shippingAddress);
$session->set('selectedDelivery', $selectedDelivery);
$session->set('cart',$cart);
if ($deliveryId === "aside") {
$session->set('selectedGifts', []);
}
$this->addFlash('success', $this->translator->trans('cart_controller.messages.delivery_modified'));
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
$shippingVAT = 0.00;
if ($selectedDelivery && $selectedDelivery instanceof Delivery) {
$shippingVAT = $selectedDelivery->getPrice() - $this->taxService->getHtPriceFromTtcPrice($selectedDelivery->getPrice());
}
$giftPriceLimit = (float)($paramsRepository->findOneBy(['name' => 'gift_limit'])->getValue());
$numberOfGiftAllowed = floor($cartService->getTotalCartPrice() / $giftPriceLimit);
$selectedGifts = $session->get('selectedGifts', []);
$numberOfGiftSelected = count($selectedGifts);
$freeVinyls = $numberOfGiftAllowed > 0 ? $promoteRepository->find(5)->getProducts() : null;
$livreurs = [
$livreurRepository->find(1),
$livreurRepository->find(2),
];
return $this->render('cart/index.html.twig', [
'current' => 'cart',
'params' => $paramsRepository->findAll(),
'cart' => $cartService->getItems(),
'total' => $cartService->getTotalCartPrice(),
'totalVAT' => $this->taxService->getIncludingVatFromCart($cart),
'shippingVAT' => $shippingVAT,
'livreurs' => $livreurs,
'shippingPrices' => $deliveryPrices,
'shippingPrice' => $selectedDelivery,
'assidable' => $shippingService->isAssidable(),
'freeVinyls' => $freeVinyls,
'numberGiftAllowed' => $numberOfGiftAllowed,
'selectedGifts' => $selectedGifts,
'numberOfGiftSelected' => $numberOfGiftSelected,
'tax' => $this->taxService->getTax()
]);
}
/**
* @Route("/paiement", name="cart_checkout")
*/
public function checkout(
ParamsRepository $paramsRepository,
CartService $cartService,
SessionInterface $session,
Request $request
): Response
{
if (!$this->isGranted('ROLE_USER')) {
$this->addFlash('warning', $this->translator->trans('cart_controller.messages.must_connect'));
return $this->redirectToRoute('app_login');
}
/** @var Uid $customer */
$customer = $this->getUser();
$cartService->init($customer->getCart());
$selectedGifts = $session->get('selectedGifts', []);
$sessionCart = $session->get('cart');
if (!$sessionCart) {
$this->addFlash('error', $this->translator->trans('cart_controller.messages.error_occurred'));
return $this->redirectToRoute('cart_index');
}
$payementType = $request->request->get('options-outlined');
if ($payementType && $payementType == 'virement') {
return $this->redirectToRoute('paiement_virement');
}
/** Vérification de la disponibilité de chaque produits */
if ($cartService->checkOutOfStockProducts() > 0) {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.out_of_stock_removed'));
return $this->redirectToRoute('cart_index');
}
$selectedDelivery = $session->get('selectedDelivery');
$shippingAddress = $session->get('shippingAddress');
// Retrait en magasin
if ($selectedDelivery == 'retrait') {
return $this->redirectToRoute('retrait_magasin');
}
if (!$selectedDelivery) {
$this->addFlash('warning', $this->translator->trans('cart_controller.messages.select_carrier'));
return $this->redirectToRoute('cart_index');
}
if ($selectedDelivery instanceof Delivery) {
if ($selectedDelivery->getLivreur()->getName() == "mondial relay" && $shippingAddress === null) {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.select_relay_point'));
return $this->redirectToRoute('cart_index');
}
}
if ($selectedDelivery == 'aside') {
$shippingPrice = 0;
}
else {
$shippingPrice = $selectedDelivery->getPrice();
}
$shippingVAT = 0.00;
if ($selectedDelivery instanceof Delivery) {
$shippingVAT = $selectedDelivery->getPrice() - $this->taxService->getHtPriceFromTtcPrice($selectedDelivery->getPrice());
}
return $this->render('cart/checkout.html.twig', [
'current' => 'cart',
'params' => $paramsRepository->findAll(),
'cart' => $cartService->getItems(),
'total' => $cartService->getTotalCartPrice(),
'shippingPrice' => $shippingPrice,
'totalVAT' => $this->taxService->getIncludingVatFromCart($sessionCart),
'shippingVAT' => $shippingVAT,
'selectedDelivery' => $selectedDelivery,
'stripePublicKey' => $this->stripePublicKey,
'typePaiement' => $payementType,
'selectedGifts' => $selectedGifts,
'tax' => $this->taxService->getTax(),
]);
}
/**
* @Route("/paiement/intent", name="paiement_intent")
*/
public function createIntent(SessionInterface $session, CartService $cartService): JsonResponse
{
/** @var Uid $customer */
$customer = $this->getUser();
$cartService->init($customer->getCart());
if ($cartService->getTotalCartPrice() <= 0) {
return new JsonResponse("Error amount must be positive", JsonResponse::HTTP_BAD_REQUEST);
}
$stripe = new \Stripe\StripeClient($this->stripeSecretKey);
$sessionCart = $session->get('cart');
$selectedDelivery = $session->get('selectedDelivery');
$shippingPrice = $selectedDelivery == "aside" || $selectedDelivery == "retrait" ? 0 : (float)$selectedDelivery->getPrice();
$cartAmount = (float)$cartService->getTotalCartPrice() + $shippingPrice;
Stripe::setApiKey($this->stripeSecretKey);
$orderRef = 'c-' . uniqid();
$productsList = [];
foreach ($sessionCart->getItems() as $id => $qty) {
$product = $this->productRepository->find($id);
$productsList[] = $product->getRef();
}
$cartRefs = implode(',', $productsList);
$paymentIntent = $stripe->paymentIntents->create([
'amount' => ($cartAmount * 100),
'currency' => 'eur',
'description' => $orderRef,
'payment_method_types' => ['card'],
'metadata' => [
"customer_id" => $customer->getId(),
"customer_mail" => $customer->getEmail(),
"cart_refs" => $cartRefs,
]
]);
$session->set('paymentIntentId', $paymentIntent->id);
$output = [
'clientSecret' => $paymentIntent->client_secret,
'order' => $orderRef,
'pi' => $paymentIntent->id,
'cart' => $productsList,
'paymentIntent' => $paymentIntent,
];
return new JsonResponse($output);
}
/**
* @Route("/paiement/success/{ref}", name="paiement_success")
*/
public function paiementSuccess(
string $ref,
EntityManagerInterface $manager,
OrderRepository $orderRepository,
ParamsRepository $paramsRepository,
CartService $cartService,
SessionInterface $session
): Response
{
/** @var Uid $customer */
$customer = $this->getUser();
$cartService->init($customer->getCart());
$now = new DateTimeImmutable();
//try {
$order = $orderRepository->findOneBy(['ref' => $ref]);
if ($order->getState() > 0) {
return $this->redirectToRoute('cart_index');
}
$selectedDelivery = $session->get('selectedDelivery');
if ($selectedDelivery == 'aside') {
$order->setState(2);
$deliveryPrice = 0;
}
else {
$order->setState(1);
$deliveryPrice = $order->getShipping();
}
$invoice = new Invoice();
$invoice->setOrdered($order);
$invoice->setCreatedAt($now);
$total = $order->getAmount() + $deliveryPrice;
$invoice->setTotal($total);
$invoice->setTax($order->getTax());
$manager->persist($invoice);
$manager->flush();
$parameters = [
'user' => $order->getUser(),
'order' => $order,
];
$headers = "From:no-reply@mazykkavinyles.fr" . "\r\n";
$headers .= "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
try {
mail($order->getUser()->getUserIdentifier(), sprintf($this->translator->trans('cart_controller.emails.order_validated'), $order->getRef()), $this->twig->render("cart/order_email.html.twig", $parameters), $headers);
} catch (\Exception $e) {
$this->logger->error("Email not send", ['message' => $e->getMessage()]);
}
$session->remove('cart');
$session->remove('order');
$session->remove('selectedDelivery');
$session->remove('shippingAddress');
$session->remove('selectedGifts');
$cartService->updateItems([]);
/* } catch (Exception $e) {
$this->addFlash('danger', $e->getMessage());
}*/
return $this->render('cart/checkout/success.html.twig', [
'current' => 'cart',
'params' => $paramsRepository->findAll(),
]);
}
/**
* @Route("/paiement/cancel/{pi}", name="paiement_cancel")
*/
public function paiementCancel($pi, EntityManagerInterface $manager, OrderRepository $orderRepository): JsonResponse
{
$stripe = new \Stripe\StripeClient($this->stripeSecretKey);
$intent = $stripe->paymentIntents->retrieve($pi,[]);
$order = $orderRepository->findOneBy(['ref' => $intent->description]);
$order->setState(4);
$manager->flush();
return new JsonResponse("Paiement canceled");
}
/**
* @Route("/paiement/virement", name="paiement_virement")
*/
public function virement(
SessionInterface $session,
ProductRepository $productRepository,
LivreurRepository $livreurRepository,
EntityManagerInterface $manager,
CartService $cartService,
ParamsRepository $paramsRepository
): Response
{
if (!$session->get('cart')) {
return $this->redirectToRoute('cart_checkout');
}
$orderRef = 'c-' . uniqid();
$cart = $session->get('cart');
$selectedDelivery = $session->get('selectedDelivery');
$shippingAddress = $session->get('shippingAddress');
if ($selectedDelivery instanceof Delivery) {
if ($selectedDelivery->getLivreur()->getName() == "mondial relay" && $shippingAddress === null) {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.select_relay_point'));
return $this->redirectToRoute('cart_index');
}
}
if ($selectedDelivery == "retrait") {
$livreur = null;
}
else {
// Récupération du livreur via le repository
$livreur = $livreurRepository->find($selectedDelivery->getLivreur()->getId());
if (!$livreur) {
throw new \Exception('Livreur non trouvé');
}
}
/** @var Uid $user */
$user = $this->getUser();
$cartService->init($user->getCart());
/** Vérification de la disponibilité de chaque produits */
if ($cartService->checkOutOfStockProducts() == 0) {
$order = new Order();
$order->setRef($orderRef);
$order->setUser($user);
$order->setCreatedAt(new DateTimeImmutable());
$order->setAmount($cartService->getTotalCartPrice());
$order->setHtShipping($this->taxService->getHtPriceFromTtcPrice($selectedDelivery->getPrice()));
$order->setShipping($selectedDelivery->getPrice());
$order->setLivreur($livreur);
$order->setPi('virement');
$order->setState(0);
$order->setLinkedTo(null);
$order->setTax($this->taxService->getTax());
if($shippingAddress){
$order->setAddress([
'recipient' => $shippingAddress->recipient,
'addressLine1' => $shippingAddress->addressLine1,
'complement' => $shippingAddress->complement,
'postalCode' => $shippingAddress->postalCode,
'city' => $shippingAddress->city,
'country' => $shippingAddress->country,
]);
}
foreach ($cart->getItems() as $id => $qty) {
$detail = new Detail();
$product = $productRepository->find($id);
$newQty = $product->getQuantity() - $qty;
if ($_ENV['APP_ENV'] === 'prod') {
$product->setQuantity($newQty);
}
$detail->setOrderId($order);
$detail->setProduct($product);
$price = $product->getPromo() > 0 ? $product->getPromo() : $product->getPrice();
$htPrice = 0.00;
if ($product->getCategory()->getName() === 'vinyles') {
/** @var Vinyl $vinyl */
$vinyl = $product;
if ($vinyl->getState() === 'neuf') {
$htPrice = $this->taxService->getHtPriceFromTtcPrice($price);
}
} else {
$htPrice = $this->taxService->getHtPriceFromTtcPrice($price);
}
$detail->setHtPrice($htPrice);
$detail->setPrice($price);
$detail->setQty($qty);
$manager->persist($detail);
$order->addDetail($detail);
}
// Calcul total HT
$htAmount = $cartService->getTotalCartPrice() - $this->taxService->getIncludingVatFromCart($cart);
$order->setHtAmount($htAmount);
// Produits offert
$selectedGifts = $session->get('selectedGifts', []);
/** @var Product $product */
foreach ($selectedGifts as $id => $product) {
$product = $productRepository->find($id);
$detail = new Detail();
$newQty = $product->getQuantity() - 1;
if ($_ENV['APP_ENV'] === 'prod') {
$product->setQuantity($newQty);
}
$detail->setOrderId($order);
$detail->setProduct($product);
$detail->setHtPrice(0.00);
$detail->setPrice(0.00);
$detail->setQty(1);
$order->addDetail($detail);
}
$manager->persist($order);
$manager->flush();
$cartService->updateItems([]);
/** Envoi mail client */
$to = [$user->getUserIdentifier()];
$parameters = [
'user' => $user,
'order' => $order,
];
$headers = "From:no-reply@mazykkavinyles.fr" . "\r\n";
$headers .= "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
try {
mail($user->getUserIdentifier(),"Commande n° {$order->getRef()} validé - Mazykka Vinyles" ,$this->twig->render("cart/order_email.html.twig", $parameters),$headers);
} catch (\Exception $e) {
$this->logger->error("Email not send", ['message' => $e->getMessage()]);
}
$session->remove('shippingAddress');
$session->remove('selectedDelivery');
$session->remove('cart');
$this->addFlash('success', $this->translator->trans('cart_controller.messages.order_saved'));
}
else {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.out_of_stock_removed'));
return $this->redirectToRoute('cart_index');
}
return $this->render('cart/checkout.html.twig', [
'current' => 'cart',
'params' => $paramsRepository->findAll(),
'cart' => [],
'total' => 0,
'typePaiement' => 'virement',
]);
}
/**
* @Route("/paiement/retrait-magasin", name="retrait_magasin")
*/
public function retrait(
SessionInterface $session,
ProductRepository $productRepository,
CartService $cartService,
EntityManagerInterface $manager,
ParamsRepository $paramsRepository
)
{
if (!$session->get('cart')) {
return $this->redirectToRoute('cart_checkout');
}
/** @var Uid $customer */
$customer = $this->getUser();
$cartService->init($customer->getCart());
$orderRef = 'c-' . uniqid();
$cart = $session->get('cart');
$user = $this->getUser();
if ($cartService->checkOutOfStockProducts() == 0) {
$order = new Order();
$order->setRef($orderRef);
$order->setUser($user);
$order->setCreatedAt(new DateTimeImmutable());
$order->setHtAmount($cartService->getTotalCartPrice() - $this->taxService->getIncludingVatFromCart($cart));
$order->setAmount($cartService->getTotalCartPrice());
$order->setHtShipping(0.00);
$order->setShipping(0.00);
$order->setLivreur(null);
$order->setPi('retrait');
$order->setState(0);
$order->setTax($this->taxService->getTax());
foreach ($cart->getItems() as $id => $qty) {
$detail = new Detail();
$product = $productRepository->find($id);
$newQty = $product->getQuantity() - $qty;
if ($_ENV['APP_ENV'] === 'prod') {
$product->setQuantity($newQty);
}
$detail->setOrderId($order);
$detail->setProduct($product);
$price = $product->getPromo() > 0 ? $product->getPromo() : $price = $product->getPrice();
$htPrice = 0.00;
if ($product->getCategory()->getName() === 'vinyles') {
/** @var Vinyl $vinyl */
$vinyl = $product;
if ($vinyl->getState() === 'neuf') {
$htPrice = $this->taxService->getHtPriceFromTtcPrice($price);
}
} else {
$htPrice = $this->taxService->getHtPriceFromTtcPrice($price);
}
$detail->setHtPrice($htPrice);
$detail->setPrice($price);
$detail->setQty($qty);
$manager->persist($detail);
$order->addDetail($detail);
}
// Calcul total HT
$htAmount = $this->taxService->getHtAmountFromOrder($order);
$order->setHtAmount($htAmount);
// Produits offert
$selectedGifts = $session->get('selectedGifts', []);
/** @var Product $product */
foreach ($selectedGifts as $id => $product) {
$product = $productRepository->find($id);
$detail = new Detail();
$newQty = $product->getQuantity() - 1;
if ($_ENV['APP_ENV'] === 'prod') {
$product->setQuantity($newQty);
}
$detail->setOrderId($order);
$detail->setProduct($product);
$detail->setPrice(0.00);
$detail->setQty(1);
$order->addDetail($detail);
}
$manager->persist($order);
$manager->flush();
$cartService->updateItems([]);
$this->addFlash('success', $this->translator->trans('cart_controller.messages.order_saved_hold'));
$parameters = [
'user' => $user,
'order' => $order,
];
$headers = "From:no-reply@mazykkavinyles.fr" . "\r\n";
$headers .= "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
try {
mail($user->getUserIdentifier(),"Commande n° {$order->getRef()} validé - Mazykka Vinyles" ,$this->twig->render("cart/order_email.html.twig", $parameters),$headers);
} catch (\Exception $e) {
$this->logger->error("Email not send", ['message' => $e->getMessage()]);
}
$session->remove('shippingAddress');
$session->remove('selectedDelivery');
$session->remove('cart');
}
else {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.out_of_stock_removed'));
return $this->redirectToRoute('cart_index');
}
return $this->render('cart/checkout.html.twig', [
'current' => 'cart',
'params' => $paramsRepository->findAll(),
'cart' => [],
'total' => 0,
'typePaiement' => 'retrait',
]);
}
/**
* @Route("/panier/add/{id}", name="cart_add")
*/
public function add(
Product $product,
CartService $cartService,
Request $request
): Response {
$quantity = isset($_REQUEST['qty']) ? (int) $_REQUEST['qty'] : 1 ;
/** @var Uid $customer */
$customer = $this->getUser();
if(null == $customer || null == $customer->getCart()) {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.must_connect_add'));
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
$cartService->init($customer->getCart());
try {
$cartService->addProduct($product, $quantity);
$this->addFlash('success', $this->translator->trans('cart_controller.messages.product_added'));
} catch (Exception $exception) {
$this->addFlash('danger',
sprintf($this->translator->trans('cart_controller.messages.product_not_added'), $exception->getMessage())
);
$this->logger->error(sprintf("Product was not added to cart : %s", $exception->getMessage()));
}
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
/**
* @Route("/panier/delete/{id}", name="cart_delete")
*/
public function delete(Product $product, CartService $cartService, Request $request): Response
{
/** @var Uid $customer */
$customer = $this->getUser();
$cartService->init($customer->getCart());
try {
$cartService->deleteProduct($product);
$this->addFlash('success', $this->translator->trans('cart_controller.messages.article_deleted'));
} catch (Exception $exception) {
$this->addFlash('error', sprintf($this->translator->trans('cart_controller.messages.error_occurred_with'), $exception->getMessage()));
}
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
/**
* @Route("/panier/gift/add/{id}", name="cart_add_gift")
*/
public function addGift(
Product $product,
CartService $cartService,
ParamsRepository $paramsRepository,
Request $request
): Response {
/** @var Uid $customer */
$customer = $this->getUser();
if(null == $customer || null == $customer->getCart()) {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.must_connect_add'));
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
$cartService->init($customer->getCart());
$giftPriceLimit = (float)($paramsRepository->findOneBy(['name' => 'gift_limit'])->getValue());
$numberOfGiftAllowed = floor($cartService->getTotalCartPrice() / $giftPriceLimit);
$selectedGifts = $this->session->get('selectedGifts', []);
$numberOfGiftSelected = count($selectedGifts);
if ($numberOfGiftAllowed <= $numberOfGiftSelected) {
$this->addFlash('danger', $this->translator->trans('cart_controller.messages.max_selection_reached'));
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
try {
$cartService->addGift($product);
$this->addFlash('success', $this->translator->trans('cart_controller.messages.selection_added'));
} catch (Exception $exception) {
$this->addFlash('danger',
sprintf($this->translator->trans('cart_controller.messages.product_not_added'), $exception->getMessage())
);
$this->logger->error(sprintf("Product was not added to cart : %s", $exception->getMessage()));
}
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
/**
* @Route("/panier/gift/delete/{id}", name="cart_delete_gift")
*/
public function deleteGift(Product $product, CartService $cartService, Request $request): Response
{
/** @var Uid $customer */
$customer = $this->getUser();
$cartService->init($customer->getCart());
try {
$cartService->deleteGift($product);
$this->addFlash('success', $this->translator->trans('cart_controller.messages.product_deleted'));
} catch (Exception $exception) {
$this->addFlash('error', sprintf($this->translator->trans('cart_controller.messages.error_occurred_with'), $exception->getMessage()));
}
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
/**
* @Route("/panier/gift/unload", name="cart_unload_gift")
*/
public function unloadGift(Request $request): Response
{
$this->session->set('selectedGifts', []);
$redirectUrl = $request->headers->get('referer');
return $this->redirect($redirectUrl);
}
private function checkQty($sessionCart, ProductRepository $productRepository, SessionInterface $session): array
{
$cart = $sessionCart->getItems();
$hsProduct = [];
foreach ($cart as $p => $qty) {
$product = $productRepository->find($p);
if($product){
if ($product->getQuantity() < 1) {
$hsProduct[] = $product;
$sessionCart['qty'] -= $qty;
$price = $product->getPromo() > 0 ? $product->getPromo() : $product->getPrice();
$sessionCart['total'] -= ($price * $qty);
unset($cart[$product->getId()]);
$sessionCart['items'] = $cart;
$session->set('cart',$sessionCart);
}
}
}
return $hsProduct;
}
/**
* @Route("/panier/add-shipping-address", name="cart_add_shipping_address")
*/
public function addShippingAddress(SessionInterface $session): JsonResponse
{
$data = $_POST;
if($data != null){
$address = new Address();
$address->recipient = $data['Nom'];
$address->addressLine1 = $data['Adresse1'];
$address->postalCode = $data['CP'];
$address->city = $data['Ville'];
$address->country = $data['Pays'];
} else {
$address = null;
}
$session->set('shippingAddress', $address);
$this->addFlash('success', 'Livraison modifiée');
return new JsonResponse(["Address added"]);
}
private function saveOrder(
SessionInterface $session,
string $pi,
LivraisonRepository $livraisonRepository,
ProductRepository $productRepository,
EntityManager $manager
)
{
$stripe = new \Stripe\StripeClient($this->stripeSecretKey);
$intent = $stripe->paymentIntents->retrieve($pi,[]);
$now = new DateTimeImmutable();
$cart = $session->get('cart');
$user = $this->getUser();
$order = new Order();
$order->setRef($intent->description);
$order->setUser($user);
$order->setCreatedAt($now);
$order->setAmount($cart['total']);
$order->setPi($pi);
if ($cart['shipping'] == 'aside') {
$order->setShipping(0.00);
$order->setState(2);
}
else {
$livraison = $livraisonRepository->find($cart['shipping']);
$order->setShipping($livraison->getPrice());
$order->setLivreur($livraison->getLivreur());
if($cart['address']){
$order->setAddress($cart['address']);
}
$order->setState(1);
}
$manager->persist($order);
foreach ($cart['items'] as $id => $qty) {
$detail = new Detail();
$product = $productRepository->find($id);
$newQty = $product->getQuantity() - $qty;
if ($_ENV['APP_ENV'] === 'prod') {
$product->setQuantity($newQty);
}
$detail->setOrderId($order);
$detail->setProduct($product);
$price = $product->getPromo() > 0 ? $product->getPromo() : $price = $product->getPrice();
$detail->setPrice($price);
$detail->setQty($qty);
$manager->persist($detail);
$order->addDetail($detail);
}
}
/**
* @Route("/paiement/preorder", name="preorder")
*/
public function preorder(
SessionInterface $session,
CartService $cartService,
LivreurRepository $livreurRepository,
ProductRepository $productRepository,
OrderRepository $orderRepository,
EntityManagerInterface $manager
): JsonResponse {
/** @var Uid $customer */
$customer = $this->getUser();
$cartService->init($customer->getCart());
$cart = $session->get('cart');
if ($cartService->getTotalCartPrice() <= 0) {
$this->logger->critical('Error : amount must be positive');
return new JsonResponse('Error : amount must be positive', Response::HTTP_BAD_REQUEST);
}
$pi = $session->get('paymentIntentId');
$selectedDelivery = $session->get('selectedDelivery');
if ($selectedDelivery == "retrait" || $selectedDelivery == "aside") {
$livreur = null;
$shippingPrice = 0;
}
else {
$livreur = $livreurRepository->find($selectedDelivery->getLivreur()->getId());
$shippingPrice = $selectedDelivery->getPrice();
}
$shippingAddress = $session->get('shippingAddress');
try {
$stripe = new \Stripe\StripeClient($this->stripeSecretKey);
$intent = $stripe->paymentIntents->retrieve($pi,[]);
$now = new DateTimeImmutable();
if(!$orderRepository->findOneBy(['pi' => $pi])) {
$order = new Order();
$order->setRef($intent->description);
$order->setUser($customer);
$order->setCreatedAt($now);
$order->setAmount($cartService->getTotalCartPrice());
$order->setPi($pi);
$order->setShipping($shippingPrice);
$order->setLivreur($livreur);
if($shippingAddress){
$order->setAddress([
'recipient' => $shippingAddress->recipient,
'addressLine1' => $shippingAddress->addressLine1,
'postalCode' => $shippingAddress->postalCode,
'city' => $shippingAddress->city,
'country' => $shippingAddress->country,
]);
}
$order->setState(0);
foreach ($cart->getItems() as $id => $qty) {
$detail = new Detail();
$product = $productRepository->find($id);
$newQty = $product->getQuantity() - $qty;
if ($_ENV['APP_ENV'] === 'prod') {
$product->setQuantity($newQty);
}
$detail->setOrderId($order);
$detail->setProduct($product);
$price = $product->getPromo() > 0 ? $product->getPromo() : $price = $product->getPrice();
$detail->setPrice($price);
$detail->setQty($qty);
$order->addDetail($detail);
}
// Produits offert
$selectedGifts = $session->get('selectedGifts', []);
/** @var Product $product */
foreach ($selectedGifts as $id => $product) {
$product = $productRepository->find($id);
$detail = new Detail();
$newQty = $product->getQuantity() - 1;
if ($_ENV['APP_ENV'] === 'prod') {
$product->setQuantity($newQty);
}
$detail->setOrderId($order);
$detail->setProduct($product);
$detail->setPrice(0.00);
$detail->setQty(1);
$order->addDetail($detail);
}
$manager->persist($order);
}
else {
$order = $orderRepository->findOneBy(['pi' => $pi]);
}
$manager->flush();
$cartService->updateItems([]);
$this->logger->info("Pre-order " . $order->getRef() . " saved");
// Preorder mail sending
$parameters = [
'user' => $order->getUser(),
'order' => $order,
];
$headers = "From:no-reply@mazykkavinyles.fr" . "\r\n";
$headers .= "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
mail(
$order->getUser()->getUserIdentifier(),
sprintf($this->translator->trans('cart_controller.emails.order_registered'), $order->getRef()),
$this->twig->render("cart/pre_order_email.html.twig", $parameters),
$headers
);
} catch (Exception $exception) {
$this->logger->error($exception->getMessage());
return new JsonResponse('Error on pre-order', Response::HTTP_BAD_REQUEST);
}
return new JsonResponse(['response' => 200]);
}
}