src/Controller/Rest/CartRestController.php line 29

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Rest;
  3. use App\Entity\CartItem;
  4. use App\Service\CartService;
  5. use Swagger\Annotations as SWG;
  6. use App\Entity\CourseOccurrence;
  7. use App\Repository\PersonRepository;
  8. use App\Repository\CartItemRepository;
  9. use FOS\RestBundle\Request\ParamFetcher;
  10. use Doctrine\Persistence\ManagerRegistry;
  11. use Nelmio\ApiDocBundle\Annotation\Model;
  12. use App\Repository\OAuth\ClientRepository;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\Security\Core\Security;
  15. use App\Repository\CourseOccurrenceRepository;
  16. use App\Repository\OAuth\AccessTokenRepository;
  17. use FOS\RestBundle\Controller\Annotations\View;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. use App\Repository\CourseOccurrenceTimeRepository;
  20. use FOS\RestBundle\Controller\Annotations\QueryParam;
  21. use App\Controller\Traits\SingleOccurrenceRequestValidatable;
  22. use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
  23. /**
  24.  * @Route("/rest/cart")
  25.  */
  26. class CartRestController extends AbstractRestCartableController
  27. {
  28.     use SingleOccurrenceRequestValidatable;
  29.     private $courseOccurrenceRepo;
  30.     protected $managerRegistry;
  31.     public function __construct(
  32.         ClientRepository $clientRepository,
  33.         AccessTokenManagerInterface $accessTokenManagerInterface,
  34.         AccessTokenRepository $accessTokenRepository,
  35.         Security $security,
  36.         CartService $cartService,
  37.         PersonRepository $personRepo,
  38.         CourseOccurrenceRepository $courseOccurrenceRepo,
  39.         ManagerRegistry $managerRegistry
  40.     ) {
  41.         parent::__construct($clientRepository$accessTokenManagerInterface$accessTokenRepository$security$managerRegistry$cartService$personRepo);
  42.         $this->courseOccurrenceRepo $courseOccurrenceRepo;
  43.         $this->managerRegistry $managerRegistry;
  44.     }
  45.     /**
  46.      * @Route("/add", name="rest_cart_add", methods="PUT")
  47.      * @SWG\Put(
  48.      *     produces={"application/json"},
  49.      *     consumes={"application/x-www-form-urlencoded"}
  50.      * )
  51.      * @SWG\Parameter(name="courseOccurrence", in="body", required=true, schema=@SWG\Schema(type="integer"))
  52.      * @SWG\Parameter(name="quantity", in="body", required=true, schema=@SWG\Schema(type="integer"))
  53.      * @SWG\Parameter(name="courseOccurrenceTime", in="body", required=false, schema=@SWG\Schema(type="integer"))
  54.      * @SWG\Response(
  55.      *     response=200,
  56.      *     description="Returns json containing a confirmation message",
  57.      *     @SWG\Schema(
  58.      *         type="object",
  59.      *         @SWG\Property(property="success", type="boolean", description="Flag if request was successful"),
  60.      *         @SWG\Property(property="message", type="string", description="Response message."),
  61.      *     )
  62.      * )
  63.      * @SWG\Response(
  64.      *     response=400,
  65.      *     description="Returned if request parameter were invalid."
  66.      * )
  67.      * @SWG\Response(
  68.      *     response=403,
  69.      *     description="Returned if access to course occurrence was denied."
  70.      * )
  71.      * @SWG\Response(
  72.      *     response=404,
  73.      *     description="Returned if course occurrence was not found."
  74.      * )
  75.      * @SWG\Tag(name="rest")
  76.      * @View(serializerGroups={"public"})
  77.      */
  78.     public function add(
  79.         Request $request
  80.         CourseOccurrenceTimeRepository $courseOccurrenceTimeRepository
  81.     )
  82.     {
  83.         $courseOccurrenceId $request->get('courseOccurrence');
  84.         $quantity $request->get('quantity');
  85.         if (empty($quantity)) {
  86.             throw new \Exception(sprintf('Der Parameter „%s“ fehlt leider.''quantity'));
  87.         }
  88.         $violation $this->validateSingleOccurrenceRequest($courseOccurrenceId$quantity);
  89.         if ($violation !== null) {
  90.             return $violation;
  91.         }
  92.         $courseOccurrence $this->getCourseOccurrence($courseOccurrenceId);
  93.         $courseOccurrenceTimeId null;
  94.         // Validate course template availability
  95.         if ($courseOccurrence->getCourse()->getCourseNature() == 'CourseTemplate') {
  96.             // Obtain course occurrence time id
  97.             $courseOccurrenceTimeId $request->get('courseOccurrenceTime');
  98.             if (empty($courseOccurrenceTimeId)) {
  99.                 throw new \Exception(sprintf('Der Parameter „%s“ fehlt leider.''courseOccurrenceTime'));
  100.             }
  101.             // Fetch time
  102.             $courseOccurrenceTime $courseOccurrenceTimeRepository->find($courseOccurrenceTimeId);
  103.             if ($courseOccurrenceTime === null) {
  104.                 throw $this->createNotFoundException('Der angegebene Zeit-Slot konnte nicht gefunden werden.');
  105.             }
  106.             if ($courseOccurrenceTime->getAvailability() == 'NotAvailable') {
  107.                 throw new \Exception(sprintf('Time is not available.'));
  108.             }
  109.             // Todo check collision with booked courses
  110.         } else {
  111.             $courseOccurrenceTime null;
  112.             if (!$courseOccurrence->isAvailable()) {
  113.                 throw $this->createNotFoundException('Dieser Kurs kann nicht in den Warenkorb gelegt werden.');
  114.             }
  115.         }
  116.         $em $this->managerRegistry->getManager();
  117.         $cart $this->getCart();
  118.         if (!$cart->getId()) {
  119.             $em->flush();
  120.         }
  121.         $cartItem $this->cartService->getCartItemIfExists($courseOccurrence$cartfalse$courseOccurrenceTimeId);
  122.         if ($cartItem) {
  123.             if ($courseOccurrence->getCourse()->getCourseNature() != 'CourseTemplate') {
  124.                 $cartItem->increaseQuantity($quantity);
  125.                 foreach ($cartItem->getMaterialCosts() as $materialCost) {
  126.                     $materialCost->increaseQuantity($quantity);
  127.                 }
  128.             }
  129.         } else {
  130.             $cartItem CartItem::createWithCart($cart$courseOccurrence$quantity$courseOccurrenceTime);
  131.             $em->persist($cartItem);
  132.             if ($courseOccurrence->getMaterialCost() > 0) {
  133.                 $materialCost CartItem::createWithCartItem($cartItem);
  134.                 $em->persist($materialCost);
  135.             }
  136.         }
  137.         $em->flush();
  138.         return [
  139.             'success' => true,
  140.             'message' => $quantity . ($quantity ' Kurse' ' Kurs') . ' in den Warenkorb gelegt.',
  141.         ];
  142.     }
  143.     /**
  144.      * @Route("/set-quantity", name="rest_cart_set-quantity", methods="PUT")
  145.      * @SWG\Put(
  146.      *     produces={"application/json"},
  147.      *     consumes={"application/x-www-form-urlencoded"}
  148.      * )
  149.      * @SWG\Parameter(name="courseOccurrence", in="body", required=true, schema=@SWG\Schema(type="integer"))
  150.      * @SWG\Parameter(name="quantity", in="body", required=true, schema=@SWG\Schema(type="integer"))
  151.      * @SWG\Response(
  152.      *     response=200,
  153.      *     description="Returns json containing a confirmation message"
  154.      * )
  155.      * @SWG\Response(
  156.      *     response=400,
  157.      *     description="Returned if request parameter were invalid."
  158.      * )
  159.      * @SWG\Response(
  160.      *     response=403,
  161.      *     description="Returned if access to course occurrence was denied."
  162.      * )
  163.      * @SWG\Response(
  164.      *     response=404,
  165.      *     description="Returned if course occurrence was not found."
  166.      * )
  167.      * @SWG\Tag(name="rest")
  168.      * @View(serializerGroups={"public"})
  169.      */
  170.     public function setQuantity(Request $request)
  171.     {
  172.         $courseOccurrenceId $request->get('courseOccurrence');
  173.         $quantity $request->get('quantity');
  174.         $violation $this->validateSingleOccurrenceRequest($courseOccurrenceId$quantity);
  175.         if ($violation !== null) {
  176.             return $this->json($violation400);
  177.         }
  178.         $courseOccurrence $this->getCourseOccurrence($courseOccurrenceId);
  179.         $cart $this->getCart();
  180.         $cartItem $this->cartService->getCartItemIfExists($courseOccurrence$cart);
  181.         if (!$cartItem) {
  182.             throw $this->createNotFoundException('The requested item is not in current cart.');
  183.         }
  184.         $message '';
  185.         if ($quantity $courseOccurrence->getFreeSlots()) {
  186.             if (!$courseOccurrence->getReservationAllowed()) {
  187.                 return [
  188.                     'success' => false,
  189.                     'message' => 'Es sind keine freien Plätze mehr verfügbar.',
  190.                 ];
  191.             }
  192.             $message 'Menge im Warenkorb aktualisiert. Es sind nicht mehr genug Plätze verfügbar. Ihre Anmeldung wird auf die Warteliste gestellt.';
  193.         }
  194.         $cartItem->setQuantity($quantity);
  195.         if ($cartItem->getMaterialCosts()) {
  196.             foreach ($cartItem->getMaterialCosts() as $materialCost) {
  197.                 $materialCost->setQuantity($quantity);
  198.             }
  199.         }
  200.         $em $this->managerRegistry->getManager();
  201.         $em->flush();
  202.         return [
  203.             'success' => true,
  204.             'message' => $message $message 'Menge im Warenkorb aktualisiert.',
  205.         ];
  206.     }
  207.     /**
  208.      * @Route("/remove", name="rest_cart_remove", methods="DELETE")
  209.      * @SWG\Delete(
  210.      *     produces={"application/json"},
  211.      *     consumes={"application/x-www-form-urlencoded"}
  212.      * )
  213.      * @SWG\Parameter(name="courseOccurrence", in="body", required=true, schema=@SWG\Schema(type="integer"))
  214.      * @SWG\Response(
  215.      *     response=200,
  216.      *     description="Returns json containing a confirmation message",
  217.      *     @SWG\Schema(
  218.      *         type="object",
  219.      *         @SWG\Property(property="success", type="boolean", description="Flag if request was successful"),
  220.      *         @SWG\Property(property="message", type="string", description="Response message."),
  221.      *     )
  222.      * )
  223.      * @SWG\Response(
  224.      *     response=400,
  225.      *     description="Returned if request parameter were invalid."
  226.      * )
  227.      * @SWG\Response(
  228.      *     response=403,
  229.      *     description="Returned if access to course occurrence was denied."
  230.      * )
  231.      * @SWG\Response(
  232.      *     response=404,
  233.      *     description="Returned if course occurrence was not found."
  234.      * )
  235.      * @SWG\Tag(name="rest")
  236.      * @View(serializerGroups={"public"})
  237.      */
  238.     public function remove(Request $request)
  239.     {
  240.         $courseOccurrenceId $request->get('courseOccurrence');
  241.         if (!is_numeric($courseOccurrenceId)) {
  242.             return $this->json([
  243.                 'success' => false,
  244.                 'message' => 'Es wurden ungültige Werte übergeben',
  245.                 'errors' => ['courseOccurrence' => 'Dieser Wert muss ein Integer sein.'],
  246.             ], 400);
  247.         }
  248.         $courseOccurrence $this->getCourseOccurrence($courseOccurrenceId);
  249.         $cart $this->getCart();
  250.         $em $this->managerRegistry->getManager();
  251.         $cartItem $this->cartService->getCartItemIfExists($courseOccurrence$cart);
  252.         if (!$cartItem) {
  253.             throw $this->createNotFoundException('Der angeforderte Kurs befindet sich nicht im Warenkorb.');
  254.         }
  255.         if ($cartItem->getMaterialCosts()) {
  256.             foreach ($cartItem->getMaterialCosts() as $materialCost) {
  257.                 $em->remove($materialCost);
  258.             }
  259.         }
  260.         $cart->removeItem($cartItem);
  261.         $em->remove($cartItem);
  262.         $em->flush();
  263.         return [
  264.             'success' => true,
  265.             'message' => 'Der Kurs wurde aus dem Warenkorb entfernt.',
  266.         ];
  267.     }
  268.     /**
  269.      * @Route("/show", name="rest_cart_show", methods="GET")
  270.      * @SWG\Get(
  271.      *     produces={"application/json"},
  272.      *     @SWG\Parameter(name="limit", in="query", type="integer"),
  273.      *     @SWG\Parameter(name="offset", in="query", type="integer"),
  274.      * )
  275.      * @QueryParam(
  276.      *     name="limit",
  277.      *     requirements="\d+",
  278.      *     default="100",
  279.      * )
  280.      * @QueryParam(
  281.      *     name="offset",
  282.      *     requirements="\d+",
  283.      *     default="0",
  284.      * )
  285.      * @QueryParam(
  286.      *     name="order",
  287.      *     requirements="asc|desc",
  288.      *     default="asc",
  289.      *     description="Possible values: asc|desc",
  290.      * )
  291.      * @QueryParam(
  292.      *     name="orderby",
  293.      *     requirements="title|price|priceSum|quantity",
  294.      *     default="title",
  295.      *     description="Possible values: title|price|priceSum|quantity",
  296.      * )
  297.      * @SWG\Response(
  298.      *     response=200,
  299.      *     description="Returns cart content in json format.",
  300.      *     @Model(type=Cart::class, groups={"personal"})
  301.      * )
  302.      * @SWG\Tag(name="rest")
  303.      * @View(serializerGroups={"personal"})
  304.      */
  305.     public function show(ParamFetcher $paramFetcherCartItemRepository $cartItemRepo)
  306.     {
  307.         $order $paramFetcher->get('order');
  308.         $orderby $paramFetcher->get('orderby');
  309.         $limit $paramFetcher->get('limit');
  310.         $offset $paramFetcher->get('offset');
  311.         $cart $this->getCart();
  312.         if ($cart->getId()) {
  313.             $cartItems $cartItemRepo->findBy(['cart' => $cart'courseItem' => null], [$orderby => $order], $limit$offset);
  314.             $cart->setItems($cartItems);
  315.         }
  316.         return $cart;
  317.     }
  318.     /**
  319.      * Get course occurrence by id. It will be checked if entity exists and access is allowed.
  320.      *
  321.      * @param $courseOccurrenceId
  322.      * @return CourseOccurrence|null
  323.      */
  324.     protected function getCourseOccurrence($courseOccurrenceId)
  325.     {
  326.         $courseOccurrence $this->courseOccurrenceRepo->findOneBy(['id' => $courseOccurrenceId]);
  327.         if (!$courseOccurrence) {
  328.             throw $this->createNotFoundException('The requested course occurrence does not exist.');
  329.         }
  330.         #$this->denyAccessUnlessGranted('frontend_client_allowed', $courseOccurrence);
  331.         return $courseOccurrence;
  332.     }
  333. }