src/Order/Controller/CartController.php line 143

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace App\Order\Controller;
  3. use App\Customer\Service\BillingAddressService;
  4. use App\Customer\Service\CustomerService;
  5. use App\Customer\Service\DeliveryAddressService;
  6. use App\Delivery\Service\DeliveryScheduleService;
  7. use App\Framework\Controller\APIController;
  8. use App\Framework\Serializer\APISerializerGroup;
  9. use App\Order\Entity\Cart;
  10. use App\Order\Service\CartService;
  11. use App\Product\Service\ProductService;
  12. use App\Stock\Service\StockService;
  13. use DateTime;
  14. use Doctrine\ORM\EntityNotFoundException;
  15. use Symfony\Component\Routing\Annotation\Route;
  16. use Symfony\Component\Serializer\Exception\LogicException;
  17. use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
  18. #[Route(path'/api/carts')]
  19. class CartController extends APIController
  20. {
  21.     private CartService $cartService;
  22.     private CustomerService $customerService;
  23.     private DeliveryAddressService $shippingAddressService;
  24.     private DeliveryScheduleService $deliveryScheduleService;
  25.     private BillingAddressService $billingAddressService;
  26.     private ProductService $productService;
  27.     private StockService $stockService;
  28.     public function __construct(
  29.         CartService $cartService,
  30.         CustomerService $customerService,
  31.         DeliveryAddressService $shippingAddressService,
  32.         DeliveryScheduleService $deliveryScheduleService,
  33.         BillingAddressService $billingAddressService,
  34.         ProductService $productService,
  35.         StockService $stockService
  36.     ) {
  37.         $this->cartService $cartService;
  38.         $this->customerService $customerService;
  39.         $this->shippingAddressService $shippingAddressService;
  40.         $this->deliveryScheduleService $deliveryScheduleService;
  41.         $this->billingAddressService $billingAddressService;
  42.         $this->productService $productService;
  43.         $this->stockService $stockService;
  44.     }
  45.     /**
  46.      * @return mixed[]
  47.      */
  48.     #[Route(path'/{id}'requirements: ['id' => '\d+'], methods: ['GET'])]
  49.     #[APISerializerGroup('cart:default''product:list''billing_address:default''streetaddress:default')]
  50.     public function getCart(int $id): array
  51.     {
  52.         $cart $this->cartService->getCartById($id);
  53.         return $this->createResponse($cart);
  54.     }
  55.     /**
  56.      * @return mixed[]
  57.      */
  58.     #[Route(path''methods: ['POST'])]
  59.     #[APISerializerGroup('cart:default''product:list')]
  60.     public function createCartAction(): array
  61.     {
  62.         $cart $this->cartService->createCart();
  63.         return $this->createResponse($cart);
  64.     }
  65.     /**
  66.      * @return mixed[]
  67.      */
  68.     #[Route(path'/{id}'requirements: ['id' => '\d+'], methods: ['PATCH'])]
  69.     #[APISerializerGroup('cart:default''product:list''streetaddress:default''billing_address:default')]
  70.     public function updateCart(int $id): array
  71.     {
  72.         $cart $this->cartService->getCartById($id);
  73.         $customerId $this->getRequestBodyData('customer'falsenull);
  74.         $customer $customerId $this->customerService->getById($customerId) : null;
  75.         $addressId $this->getRequestBodyData('shippingAddress'falsenull);
  76.         $address $addressId $this->shippingAddressService->getAddressById($addressId) : null;
  77.         $billingAddressId $this->getRequestBodyData('billingAddress'falsenull);
  78.         $billingAddress $billingAddressId $this->billingAddressService->getAddressById($billingAddressId) : null;
  79.         $schedule $this->getRequestBodyData('schedule'falsenull);
  80.         if ($schedule && is_numeric($schedule)) {
  81.             $schedule $this->deliveryScheduleService->getScheduleById($schedule);
  82.         } elseif ($schedule) {
  83.             $schedule['start'] = new DateTime($schedule['start']);
  84.             $schedule['end'] = new DateTime($schedule['end']);
  85.             $schedule['date'] = new DateTime($schedule['date']);
  86.         }
  87.         $orderType $this->getRequestBodyData('orderType'falsenull);
  88.         if ($customer !== null) {
  89.             $this->cartService->updateCartCustomer($cart$customer);
  90.         }
  91.         if ($address !== null) {
  92.             $this->cartService->updateCartShippingAddress($cart$address);
  93.         }
  94.         if ($billingAddress !== null) {
  95.             $this->cartService->updateCartBillingAddress($cart$billingAddress);
  96.         }
  97.         if ($schedule) {
  98.             if (is_array($schedule)) {
  99.                 $this->cartService->updateCartDeliveryCustomSchedule($cart$schedule);
  100.             } else {
  101.                 $this->cartService->updateCartDeliverySchedule($cart$schedule);
  102.             }
  103.         }
  104.         if ($orderType) {
  105.             $this->cartService->updateCartOrderType($cart$orderType);
  106.         }
  107.         return $this->createResponse($cart);
  108.     }
  109.     /**
  110.      * @throws EntityNotFoundException
  111.      *
  112.      * @return mixed[]
  113.      */
  114.     #[Route(path'/{id}'requirements: ['id' => '\d+'], methods: ['PUT'])]
  115.     #[APISerializerGroup('cart:default''product:list')]
  116.     public function addAction(Cart $cart): array
  117.     {
  118.         $productId = (int) $this->getRequestBodyData('product'true);
  119.         $quantity = (int) $this->getRequestBodyData('quantity'true);
  120.         $product $this->productService->getProductById($productId);
  121.         // Add the product to the cart
  122.         if ($quantity 0) {
  123.             $this->cartService->add($cart$product$quantity);
  124.         } else {
  125.             $this->cartService->remove($cart$product, -$quantity);
  126.         }
  127.         return $this->createResponse($cart);
  128.     }
  129.     /**
  130.      * @throws LogicException
  131.      * @throws NotNormalizableValueException
  132.      *
  133.      * @return array<string, mixed>
  134.      */
  135.     private function createResponse(Cart $cart): array
  136.     {
  137.         $result = [];
  138.         $result['id'] = $cart->getId();
  139.         $result['billingAddress'] = $cart->getBillingAddress();
  140.         $result['customer'] = $cart->getCustomer();
  141.         $result['shippingAddress'] = $cart->getShippingAddress();
  142.         $result['deliveryDate'] = $cart->getDeliveryDate();
  143.         $result['deliveryStartTime'] = $cart->getDeliveryStartTime();
  144.         $result['deliveryEndTime'] = $cart->getDeliveryEndTime();
  145.         $result['items'] = $cart->getItems();
  146.         $productsSubTotal 0.0;
  147.         $shippingSubTotal 0.0;
  148.         // Get stock for the products
  149.         $result['stock'] = [];
  150.         foreach ($cart->getItems() as $item) {
  151.             $product $item->getProduct();
  152.             if ($product->getType() === 'shipping') {
  153.                 $shippingSubTotal += $product->getPrice() * $item->getQuantity();
  154.             } else {
  155.                 $productsSubTotal += $product->getPrice() * $item->getQuantity();
  156.             }
  157.             $publicSale $item->getProduct()->getPublicSale();
  158.             $stock $this->stockService->getStockByProduct($product);
  159.             if ($stock != null) {
  160.                 $result['stock'][] = [
  161.                     'product' => $stock->getProduct()->getId(),
  162.                     'stock' => $publicSale $stock->getCurrentStock() : 0,
  163.                 ];
  164.             }
  165.         }
  166.         // Fetch discounts if any
  167.         $discounts $this->cartService->getDiscountsForOrder($cart);
  168.         $discountTotal 0;
  169.         foreach ($discounts as $discount) {
  170.             $discountTotal += $discount['amount'];
  171.         }
  172.         $errors $this->cartService->getValidationErrors($cart);
  173.         // Now calculate the actual total cost
  174.         $total $productsSubTotal $shippingSubTotal $discountTotal;
  175.         $result['subtotal'] = $productsSubTotal;
  176.         $result['shippingCost'] = $shippingSubTotal;
  177.         $result['total'] = $total;
  178.         $result['discounts'] = $discounts;
  179.         $result['errors'] = $errors;
  180.         return $result;
  181.     }
  182. }