<?php declare(strict_types=1);
namespace App\Order\Entity;
use App\Customer\Entity\BillingAddress;
use App\Customer\Entity\Customer;
use App\Customer\Entity\StreetAddress;
use App\Delivery\Entity\DeliverySchedule;
use App\Framework\Entity\BlameableEntityTrait;
use App\Framework\Entity\TimestampableEntityTrait;
use App\Product\Entity\Product;
use DateTime;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table
*/
class Cart
{
use BlameableEntityTrait;
use TimestampableEntityTrait;
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private int $id;
/**
* @ORM\Column(type="string", length=100, options={"default" : "normal"})
*/
private string $orderType;
/**
* @ORM\ManyToOne(targetEntity="App\Customer\Entity\Customer")
*/
protected ?Customer $customer = null;
/**
* @ORM\ManyToOne(targetEntity="App\Customer\Entity\StreetAddress")
*/
protected ?StreetAddress $shippingAddress = null;
/**
* @ORM\ManyToOne(targetEntity="App\Customer\Entity\BillingAddress")
*/
protected ?BillingAddress $billingAddress = null;
/**
* @ORM\ManyToOne(targetEntity="App\Delivery\Entity\DeliverySchedule")
*/
protected ?DeliverySchedule $deliverySchedule = null;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected ?DateTime $deliveryDate = null;
/**
* @ORM\Column(type="time", nullable=true)
*/
private ?DateTime $deliveryStartTime = null;
/**
* @ORM\Column(type="time", nullable=true)
*/
private ?DateTime $deliveryEndTime = null;
/**
* @ORM\OneToMany(targetEntity="App\Order\Entity\CartItem", mappedBy="cart", fetch="EAGER", cascade={"persist", "remove"}, orphanRemoval=true)
**/
private Collection $items;
/**
* @ORM\ManyToOne(targetEntity="App\Product\Entity\Product")
*/
private ?Product $shippingProduct = null;
public function __construct()
{
$this->items = new ArrayCollection();
$this->orderType = 'normal';
}
public function getId(): int
{
return $this->id;
}
public function getOrderType(): string
{
return $this->orderType;
}
public function setOrderType(string $type): void
{
$this->orderType = $type;
}
/**
* @return CartItem[]
*/
public function getItems(): array
{
return array_values($this->items->toArray());
}
/**
* @param CartItem[] $items
*/
public function setItems(array $items): void
{
$this->items = $items;
}
public function addItem(CartItem $item): static
{
$this->items[] = $item;
$item->setCart($this);
return $this;
}
/**
* @return mixed|null
*/
public function getItem(Product $product)
{
foreach ($this->items as $i) {
if ($i->getProduct()->getId() === $product->getId()) {
return $i;
}
}
return null;
}
public function removeItem(CartItem $item): void
{
$this->items->removeElement($item);
}
public function getCustomer(): ?Customer
{
return $this->customer;
}
public function setCustomer(?Customer $customer): void
{
$this->customer = $customer;
}
public function getShippingAddress(): ?StreetAddress
{
return $this->shippingAddress;
}
public function setShippingAddress(?StreetAddress $address): void
{
$this->shippingAddress = $address;
}
public function getBillingAddress(): ?BillingAddress
{
return $this->billingAddress;
}
public function setBillingAddress(?BillingAddress $billingAddress): void
{
$this->billingAddress = $billingAddress;
}
public function getDeliverySchedule(): ?DeliverySchedule
{
return $this->deliverySchedule;
}
public function setDeliverySchedule(?DeliverySchedule $deliverySchedule): void
{
$this->deliverySchedule = $deliverySchedule;
}
public function getDeliveryDate(): ?DateTime
{
return $this->deliveryDate;
}
/**
* @param class-string<DateTime>|null $deliveryDate
*/
public function setDeliveryDate(?DateTime $deliveryDate): void
{
$this->deliveryDate = $deliveryDate;
}
public function getDeliveryStartTime(): ?DateTimeInterface
{
return $this->deliveryStartTime;
}
/**
* @param class-string<DateTime>|null $start
*/
public function setDeliveryStartTime(?DateTime $start): void
{
$this->deliveryStartTime = $start;
}
public function getDeliveryEndTime(): ?DateTimeInterface
{
return $this->deliveryEndTime;
}
/**
* @param class-string<DateTime>|null $end
*/
public function setDeliveryEndTime(?DateTime $end): void
{
$this->deliveryEndTime = $end;
}
public function getShippingCartProduct(): ?Product
{
return $this->shippingProduct;
}
public function setShippingCartProduct(?Product $shippingProduct): void
{
$this->shippingProduct = $shippingProduct;
}
public function getSubtotal(): float
{
$total = 0;
foreach ($this->items as $item) {
$total += $item->getQuantity() * $item->getProduct()->getPrice();
}
return $total;
}
public function getProductsSubtotal(): float
{
$total = 0;
foreach ($this->items as $item) {
if ($item->getProduct()->getType() !== 'product') {
continue;
}
$total += $item->getQuantity() * $item->getProduct()->getPrice();
}
return $total;
}
public function getShippingCost(): float
{
return $this->shippingProduct !== null ? $this->shippingProduct->getPrice() : 0;
}
}