<?php
declare(strict_types=1);
namespace App\Service;
use App\Dto\CartItem;
use App\Dto\ShoppingCart;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class ShoppingCartService {
/** @var EntityManagerInterface */
protected $entityManager;
/** @var ProductService */
protected $productService;
/** @var SessionInterface */
protected $session;
/** @var TenantService */
protected $tenantService;
/**
* @param EntityManagerInterface $entityManager
* @param ProductService $productService
* @param SessionInterface $session
* @param TenantService $tenantService
*/
public function __construct(
EntityManagerInterface $entityManager,
ProductService $productService,
SessionInterface $session,
TenantService $tenantService
) {
$this->entityManager = $entityManager;
$this->productService = $productService;
$this->session = $session;
$this->tenantService = $tenantService;
}
/**
* @return array<int, CartItem>
*/
public function getCartItems(): array {
$cart = $this->getCart();
return $cart->getItems();
}
/**
* Returns the number of items in the shopping cart.
*
* @return int
*/
public function getNumberOfItems(): int {
$numberOfItems = 0;
$cart = $this->getCart();
foreach ($cart->getItems() as $item) {
$numberOfItems += $item->getQuantity();
}
return $numberOfItems;
}
/**
* Returns true or false depending on wether the shopping cart
* contains products that needs configuration.
*
* @return bool
*/
public function hasTiProduct(): bool {
$cart = $this->getCart();
foreach ($cart->getItems() as $item) {
$product = $this->productService->findProduct($item->getProductId());
if ($product->getNeedsConfirmation()) {
return true;
}
}
return false;
}
/**
* Returns the total price of the shopping cart.
*
* @return float
*/
public function getTotalPrice(): float {
$totalPrice = 0;
$cart = $this->getCart();
foreach ($cart->getItems() as $item) {
$totalPrice += $item->getPrice() * $item->getQuantity();
}
return $totalPrice;
}
/**
* Returns the total recurring price of the shopping cart.
*
* @return float
*/
public function getTotalRecurringPrice(): float {
$totalRecurringPrice = 0;
$cart = $this->getCart();
foreach ($cart->getItems() as $item) {
$totalRecurringPrice += $item->getRecurringPrice();
}
return $totalRecurringPrice;
}
/**
* Adds an item to the shopping cart.
*
* @param CartItem $cartItem
*
* @return bool
*/
public function addItem(CartItem $cartItem): bool {
$currentCart = $this->getCart();
$newCart = $currentCart->addCartItem($cartItem);
return $this->setCart($newCart);
}
/**
* Removes an item from the shopping cart.
*
* @param CartItem $cartItem
*
* @return bool
*/
public function removeItem(CartItem $cartItem): bool {
$cart = $this->getCart();
$cart = $cart->removeCartItem($cartItem);
return $this->setCart($cart);
}
/**
* Decreases the quantity of an item in the shopping cart.
* If the quantity is already 1, the item is removed from the shopping cart.
*
* @param CartItem $cartItem
*
* @return bool
*/
public function decreaseQuantity(CartItem $cartItem): bool {
$cart = $this->getCart();
$cart = $cart->decreaseQuantity($cartItem);
return $this->setCart($cart);
}
/**
* Increases the quantity of an item in the shopping cart.
*
* @param CartItem $cartItem
*
* @return bool
*/
public function increaseQuantity(CartItem $cartItem): bool {
$cart = $this->getCart();
$cart = $cart->increaseQuantity($cartItem);
return $this->setCart($cart);
}
/**
* Removes all items from the shopping cart.
*/
public function clear(): void {
$this->setCart(new ShoppingCart());
}
/**
* Returns the shopping cart.
*
* @return ShoppingCart
*/
public function getCart(): ShoppingCart {
return $this->session->get('cart', new ShoppingCart());
}
/**
* Sets the shopping cart.
*
* @param ShoppingCart $cart
*
* @return bool
*/
public function setCart(ShoppingCart $cart): bool {
$currentCart = $this->getCart();
$this->session->set('cart', $cart);
$response = false;
if (count($currentCart->getItems()) === 0) {
return true;
}
$response = $this->isEqual($currentCart, $cart);
return $response;
}
/**
* Returns true if the given shopping carts are equal.
*
* @return bool
*/
public function isEqual(ShoppingCart $cart1, ShoppingCart $cart2): bool {
if ($cart1->getItems() == $cart2->getItems()) {
return true;
}
return false;
}
}