<?php
namespace App\Entity;
use App\Interfaces\ProductInterface;
use App\Model\CartInfo;
use App\Repository\CartRepository;
use App\Traits\DateTrait;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(indexes={
* @ORM\Index(columns={"serial_cookie"})
* })
* @ORM\Entity(repositoryClass=CartRepository::class)
*/
class Cart
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private ?int $id;
/**
* @ORM\Column(type="string", length=64, nullable=true)
*/
private ?string $shippingMethod;
/**
* @ORM\Column(type="string", length=64)
*/
private ?string $serialCookie;
/**
* @ORM\Column(type="boolean", options={"default": true})
*/
private bool $sameAddressBilling = TRUE;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private ?int $shippingDelay;
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="carts", cascade={"persist"})
* @ORM\JoinColumn(nullable=true)
*/
private ?User $user;
/**
* @ORM\Column(type="boolean", options={"default": false})
*/
private bool $multiShipping = FALSE;
/**
* @ORM\Column(type="decimal", precision=12, scale=4, nullable=true)
*/
private ?string $bonusTotalUsed;
/**
* @ORM\OneToOne(targetEntity=CartAddress::class, cascade={"persist", "remove"}, orphanRemoval=true)
*/
private ?CartAddress $shippingAddress;
/**
* @ORM\OneToOne(targetEntity=CartAddress::class, cascade={"persist", "remove"}, orphanRemoval=true)
*/
private ?CartAddress $billingAddress;
/**
* @ORM\OneToMany(targetEntity=CartItem::class, mappedBy="cart", cascade={"remove"})
*/
private Collection $items;
/**
* @ORM\OneToOne(targetEntity=SaleOrder::class, mappedBy="cart", cascade={"persist", "remove"})
*/
private ?SaleOrder $saleOrder;
/**
* @ORM\OneToMany(targetEntity=PointTransaction::class, mappedBy="paidCart")
*/
private Collection $paidPointTransactions;
/**
* @ORM\OneToMany(targetEntity=PointTransaction::class, mappedBy="cart")
*/
private Collection $pointTransactions;
public ?CartInfo $cartInfo = null;
use DateTrait;
public function __construct()
{
$this->items = new ArrayCollection();
$this->paidPointTransactions = new ArrayCollection();
$this->pointTransactions = new ArrayCollection();
}
public function __toString()
{
return 'Panier '.$this->getId();
}
/*
* ============================================================================================
* =============================== FONCTIONS CUSTOM ===========================================
* ============================================================================================
*/
public function getReference(): string
{
$id = strval($this->getId());
return str_pad($id, 8, '0', STR_PAD_LEFT);
}
// ITEMS
public function getId(): ?int
{
return $this->id;
}
// @TODO check product, dans la 2.8 ca ne fct pas non plus
// public function getTotalHt()
// {
// $total = NULL;
// /* @var $item CartItem */
// foreach ( $this->items as $item ) {
// $total += $item->getProduct()->getPriceHT() * $item->getQuantity();
// }
// return $total;
// }
//
//
// public function getTotalTTC()
// {
// $total = NULL;
// /** @var CartItem $item */
// foreach ( $this->items as $item ) {
// $total += $item->getProduct()->getPriceTTC() * $item->getQuantity();
// }
// return $total;
// }
public function getItemsCount(): int
{
return count($this->items);
}
/**
* @param ProductInterface $product
*
* @return CartItem|false
*/
public function getCartItemByProduct(ProductInterface $product)
{
foreach ($this->getItems() as $item) {
if ($item->getSku() == $product->getSku()) {
return $item;
}
}
return FALSE;
}
/**
* @return Collection|CartItem[]
*/
public function getItems(): Collection
{
return $this->items;
}
public function getAddressType(Address $address): string
{
if ($this->billingAddress == $address) {
return Address::TYPE_BILLING_ADDRESS;
} elseif ($this->shippingAddress == $address) {
return Address::TYPE_SHIPPING_ADDRESS;
}
return Address::TYPE_BILLING_ADDRESS;
}
/*
* ============================================================================================
* ============================== FIN FONCTIONS CUSTOM ========================================
* ============================================================================================
*/
public function getCartItemById($id)
{
foreach ($this->getItems() as $item) {
if ($item->getId() == $id) {
return $item;
}
}
return FALSE;
}
public function totalQuantity()
{
$totalQuantity = 0;
foreach ($this->getItems() as $item) {
$totalQuantity += $item->getQuantity();
}
return $totalQuantity;
}
public function getShippingMethod(): ?string
{
return $this->shippingMethod;
}
public function setShippingMethod(?string $shippingMethod): self
{
$this->shippingMethod = $shippingMethod;
return $this;
}
public function getSerialCookie(): ?string
{
return $this->serialCookie;
}
public function setSerialCookie(string $serialCookie): self
{
$this->serialCookie = $serialCookie;
return $this;
}
public function getSameAddressBilling(): ?bool
{
return $this->sameAddressBilling;
}
public function setSameAddressBilling(bool $sameAddressBilling): self
{
$this->sameAddressBilling = $sameAddressBilling;
return $this;
}
public function getShippingDelay(): ?int
{
return $this->shippingDelay;
}
public function setShippingDelay(?int $shippingDelay): self
{
$this->shippingDelay = $shippingDelay;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getMultiShipping(): ?bool
{
return $this->multiShipping;
}
public function setMultiShipping(bool $multiShipping): self
{
$this->multiShipping = $multiShipping;
return $this;
}
public function getBonusTotalUsed(): ?string
{
return $this->bonusTotalUsed;
}
public function setBonusTotalUsed(?string $bonusTotalUsed): self
{
$this->bonusTotalUsed = $bonusTotalUsed;
return $this;
}
public function getShippingAddress(): ?CartAddress
{
return $this->shippingAddress;
}
public function setShippingAddress(?CartAddress $shippingAddress): self
{
$this->shippingAddress = $shippingAddress;
return $this;
}
public function getBillingAddress(): ?CartAddress
{
return $this->billingAddress;
}
public function setBillingAddress(?CartAddress $billingAddress): self
{
$this->billingAddress = $billingAddress;
return $this;
}
public function addItem(CartItem $item): self
{
if (!$this->items->contains($item)) {
$this->items[] = $item;
$item->setCart($this);
}
return $this;
}
public function removeItem(CartItem $item): self
{
if ($this->items->removeElement($item)) {
// set the owning side to null (unless already changed)
if ($item->getCart() === $this) {
$item->setCart(NULL);
}
}
return $this;
}
public function getSaleOrder(): ?SaleOrder
{
return $this->saleOrder;
}
public function setSaleOrder(?SaleOrder $saleOrder): self
{
// unset the owning side of the relation if necessary
if ($saleOrder === NULL && $this->saleOrder !== NULL) {
$this->saleOrder->setCart(NULL);
}
// set the owning side of the relation if necessary
if ($saleOrder !== NULL && $saleOrder->getCart() !== $this) {
$saleOrder->setCart($this);
}
$this->saleOrder = $saleOrder;
return $this;
}
/**
* @return Collection|PointTransaction[]
*/
public function getAllPointTransactions(): Collection
{
$all = $this->pointTransactions;
foreach($this->paidPointTransactions as $transaction)
{
if($all->contains($transaction)) continue;
$all->add($transaction);
}
return $all;
}
/**
* @return Collection|PointTransaction[]
*/
public function getPaidPointTransactions(): Collection
{
return $this->paidPointTransactions;
}
/**
* @param PointTransaction $transaction
*
* @return $this
*/
public function addPaidPointTransaction(PointTransaction $transaction): self
{
if(!$this->paidPointTransactions->contains($transaction))
{
$this->paidPointTransactions[] = $transaction;
if($transaction->getPaidCart() !== $this) $transaction->setPaidCart($this);
}
return $this;
}
/**
* @param PointTransaction $transaction
*
* @return $this
*/
public function removePaidPointTransaction(PointTransaction $transaction): self
{
if($this->paidPointTransactions->removeElement($transaction) && $transaction->getPaidCart() === $this)
{
$transaction->setPaidCart();
}
return $this;
}
/**
* @param iterable|PointTransaction[] $transactions
*
* @return $this
*/
public function setPaidPointTransactions(iterable $transactions): self
{
foreach($this->paidPointTransactions as $transaction)
{
$this->removePaidPointTransaction($transaction);
}
foreach($transactions as $transaction)
{
$this->addPaidPointTransaction($transaction);
}
return $this;
}
/**
* @param bool $excludeValids
* @param bool $onlyValids
* @param string|null $onlyValids
*
* @return float
*/
public function getTotalPaidPointTransactions(bool $excludeValids = false, bool $onlyValids = false, ?string $pointCategory = null): float
{
$points = 0;
foreach($this->getPaidPointTransactions() as $transaction)
{
if($excludeValids && $transaction->getValue() != 0) continue;
if($onlyValids && $transaction->getValue() == 0) continue;
if ($pointCategory !== null && $transaction->getCategory() !== $pointCategory) continue;
$points += $transaction->getPaymentValue();
}
return round($points, 2);
}
/**
* @return Collection|PointTransaction[]
*/
public function getPointTransactions(): Collection
{
return $this->pointTransactions;
}
/**
* @param PointTransaction $transaction
*
* @return $this
*/
public function addPointTransaction(PointTransaction $transaction): self
{
if(!$this->pointTransactions->contains($transaction))
{
$this->pointTransactions[] = $transaction;
if($transaction->getCart() !== $this) $transaction->setCart($this);
}
return $this;
}
/**
* @param PointTransaction $transaction
*
* @return $this
*/
public function removePointTransaction(PointTransaction $transaction): self
{
if($this->pointTransactions->removeElement($transaction) && $transaction->getCart() === $this)
{
$transaction->setCart(null);
}
return $this;
}
/**
* @param iterable|PointTransaction[] $transactions
*
* @return $this
*/
public function setPointTransactions(iterable $transactions): self
{
foreach($this->pointTransactions as $transaction)
{
$this->removePointTransaction($transaction);
}
foreach($transactions as $transaction)
{
$this->addPointTransaction($transaction);
}
return $this;
}
}