<?php
namespace App\Controller;
use App\Config\CartConfig;
use App\Entity\Speaker;
use App\Entity\SpeakerConsultation;
use App\Entity\SpeakerCourse;
use App\Form\SpeakerOrderType;
use App\Repository\PromoCodeRepository;
use App\Repository\SpeakerConsultationRepository;
use App\Service\CartService;
use App\Service\DiscountService;
use App\Service\OrderService;
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\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* @Route("/cart")
*/
class CartController extends AbstractController
{
/**
* @Route("/", name="cart.index")
*/
public function index(
CartService $cartService,
SpeakerConsultationRepository $consultationRepository,
PromoCodeRepository $promoCodeRepository,
OrderService $orderService
): Response
{
$now = new \DateTime();
if ($cartService->getExpired() < $now) {
$cartService->clearConsultations();
}
$promoCodes = $cartService->getPromoCodes();
$data = [];
$cartConsultations = $cartService->getConsultations();
foreach ($consultationRepository->findBy(['id' => $cartService->getConsultationsIds()], ['startDate' => 'asc']) as $consultation) {
$id = $consultation->getSpeaker()->getId();
$data[$id]['speaker'] = $consultation->getSpeaker();
$data[$id]['consultations'][] = array_merge($cartConsultations[$id][$consultation->getId()], [
'entity' => $consultation,
]);
}
// Get services
foreach ($cartService->getServices() as $idSpeaker => $service) {
$data[$idSpeaker]['speaker'] = $this->getDoctrine()->getRepository(Speaker::class)->find($idSpeaker);
$data[$idSpeaker]['services'] = $service;
}
// Get premium package
foreach ($cartService->getPremiumPackages() as $idSpeaker => $premiumPackage) {
$data[$idSpeaker]['speaker'] = $this->getDoctrine()->getRepository(Speaker::class)->find($idSpeaker);
$data[$idSpeaker]['packages'] = $premiumPackage;
}
// Get courses
foreach ($cartService->getCourses() as $idSpeaker => $courses) {
$data[$idSpeaker]['speaker'] = $this->getDoctrine()->getRepository(Speaker::class)->find($idSpeaker);
$data[$idSpeaker]['courses'] = $this->getDoctrine()->getRepository(SpeakerCourse::class)->findBy(['id' => $courses]);
}
ksort($data);
if (empty($data)) {
return $this->render('cart/empty.html.twig', []);
}
// Add discount service
foreach ($data as $id => $item) {
$discountService = new DiscountService();
$discountService->setConsultationsCount(count($item['consultations'] ?? []));
if (isset($promoCodes[$id]) && $promo = $promoCodeRepository->find($promoCodes[$id])) {
$discountService->setPromoCode($promo);
}
$data[$id]['discountService'] = $discountService;
}
return $this->render('cart/index.html.twig', ['data' => $data, 'timezone' => $cartService->getTimeZone(), 'total' => $orderService->getTotal()]);
}
/**
* @Route("/add-cons", name="cart.add")
*/
public function addConsultation(TranslatorInterface $translator, Request $request, CartService $cartService): JsonResponse
{
//if (!$cartService->freezeConsultation($request->get('id'), $request->get('type'))) {
if (!$cartService->freezeConsultation($request->get('id'), 'price')) {
return $this->json([
'success' => false,
'message' => $translator->trans('message.cart_info_consultation_ordered'),
]);
}
return $this->json([
'success' => true,
'min' => CartConfig::FREEZE_MIN,
'message' => sprintf($translator->trans('message.cart_info_consultation'), CartConfig::FREEZE_MIN),
]);
}
/**
* @Route("/info", name="cart.info")
*/
public function info(CartService $cartService): JsonResponse
{
$now = new \DateTime();
$expired = $cartService->getExpired();
if ($expired < $now) {
$cartService->clearConsultations();
}
return $this->json([
'count' => $cartService->getItemsCount(),
'expired' => $expired ? $expired->getTimestamp() - $now->getTimestamp() : 0,
]);
}
/**
* @Route("/add-promo", name="cart.add_promo")
*/
public function addPromoCode(
Request $request,
CartService $cartService,
PromoCodeRepository $repository,
TranslatorInterface $translator
): JsonResponse
{
$promo = $repository->findOneBy(['code' => $request->get('code'), 'speaker' => (int)$request->get('speaker')]);
if ($promo) {
$cartService->addPromoCode($promo);
return $this->json([
'success' => true,
'message' => sprintf($translator->trans('message.promo_code_applied'), $promo->getAmount() . '%')
]);
}
// Try to remove previews promo code
$cartService->removePromoCodeBySpeakerId((int)$request->get('speaker'));
return $this->json([
'success' => false,
'message' => sprintf($translator->trans('message.promo_code_not_found'), $request->get('code'))
]);
}
/**
* @Route("/delete/{consultation}", name="cart.remove_cons")
* @param SpeakerConsultation $consultation
* @param CartService $cartService
* @return RedirectResponse
*/
public function removeConsultation(SpeakerConsultation $consultation, CartService $cartService): RedirectResponse
{
$cartService->removeConsultation($consultation);
return $this->redirectToRoute('cart.index');
}
/**
* @Route("/quick-add-consultation/{speaker}", name="cart.quick_add_cons")
* @param Speaker $speaker
* @param CartService $cartService
* @param PromoCodeRepository $repository
* @return Response
*/
public function quickAddConsultation(Speaker $speaker, CartService $cartService, PromoCodeRepository $repository): Response
{
$promo = $cartService->getPromoCodes();
return $this->render('cart/add_cons.html.twig', [
'speaker' => $speaker,
'orderForm' => $this->createForm(SpeakerOrderType::class)->createView(),
'promoVal' => isset($promo[$speaker->getId()]) ? $repository->find($promo[$speaker->getId()]) : '',
]);
}
/**
* @Route("/quick-edit-consultation/{consultation}", name="cart.quick_edit_cons")
* @param SpeakerConsultation $consultation
* @param CartService $cartService
* @return RedirectResponse
*/
public function changeConsultation(SpeakerConsultation $consultation, CartService $cartService): RedirectResponse
{
$cartService->removeConsultation($consultation);
return $this->redirectToRoute('cart.quick_add_cons', ['speaker' => $consultation->getSpeaker()->getId()]);
}
/**
* @Route("/add-service", name="cart.add_service")
* @param Request $request
* @param CartService $cartService
* @return RedirectResponse
*/
public function addService(Request $request, CartService $cartService): RedirectResponse
{
$code = $request->get('service');
$const = strtoupper($code);
if (!defined('App\Config\PremiumServiceConfig::' . $const)) {
$this->addFlash('error', 'message.service_not_found');
return $this->redirectToRoute('cabinet.premium.index');
}
$cartService->setTimeZone($this->getUser()->getTimezone())->addService($code, $this->getUser()->getSpeaker());
return $this->redirectToRoute('cart.index');
}
/**
* @Route("/remove-service/{code}", name="cart.remove_service")
* @param $code
* @param CartService $cartService
* @return RedirectResponse
*/
public function removeService($code, CartService $cartService): RedirectResponse
{
$cartService->removeService($code, $this->getUser()->getSpeaker());
return $this->redirectToRoute('cart.index');
}
/**
* @Route("/add-premium", name="cart.add_premium_package")
* @param Request $request
* @param CartService $cartService
* @return RedirectResponse
*/
public function addPremiumPackage(Request $request, CartService $cartService): RedirectResponse
{
$code = $request->get('package');
$const = strtoupper($code);
if (!defined('App\Config\PremiumPackageConfig::' . $const)) {
$this->addFlash('error', 'message.premium_package_not_found');
return $this->redirectToRoute('cabinet.premium.index');
}
$cartService->setTimeZone($this->getUser()->getTimezone())->addPremiumPackage($code, $this->getUser()->getSpeaker());
return $this->redirectToRoute('cart.index');
}
/**
* @Route("/remove-premium/{code}", name="cart.remove_premium_package")
* @param $code
* @param CartService $cartService
* @return RedirectResponse
*/
public function removePremiumPackage($code, CartService $cartService): RedirectResponse
{
$cartService->removePremiumPackage($code, $this->getUser()->getSpeaker());
return $this->redirectToRoute('cart.index');
}
/**
* @Route("/add-course/{course}", name="cart.add_course")
* @param SpeakerCourse $course
* @param CartService $cartService
* @param TranslatorInterface $translator
* @return JsonResponse
*/
public function addCourse(SpeakerCourse $course, CartService $cartService, TranslatorInterface $translator): JsonResponse
{
$courses = $cartService->getCourses();
if (!empty($courses[$course->getSpeaker()->getId()]) && in_array($course->getId(), $courses[$course->getSpeaker()->getId()])) {
return $this->json([
'success' => false,
'message' => $translator->trans('message.cart_course_ordered'),
]);
}
$cartService->addCourse($course);
return $this->json([
'success' => true,
'message' => $translator->trans('message.cart_course_added'),
]);
}
/**
* @Route("/remove-course/{course}", name="cart.remove_course")
* @param SpeakerCourse $course
* @param CartService $cartService
* @return RedirectResponse
*/
public function removeCourse(SpeakerCourse $course, CartService $cartService): RedirectResponse
{
$cartService->removeCourse($course);
return $this->redirectToRoute('cart.index');
}
}