<?php
declare(strict_types=1);
namespace App\Entity\ECommerce;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use App\Entity\ECommerce\Interfaces\ECUserInterface;
use App\Entity\ECommerce\Traits\DatesInterface;
use App\Entity\ECommerce\Traits\DatesTrait;
use App\Entity\App\User;
use Stringable;
use Symfony\Component\Validator\Constraints;
/**
* Cart
*
* @ORM\Table(name="cart")
*
* @ORM\Entity(repositoryClass="App\Repository\ECommerce\CartRepository")
*/
class Cart implements DatesInterface, Stringable
{
/**
* Money calculations rounding precision
*/
public const int ROUNDING_PRECISION = 2;
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $id;
/**
* @var bool
*
* @ORM\Column(name="payed", type="boolean")
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $payed = false;
/**
* @var bool
*
* @ORM\Column(name="checked_out", type="boolean")
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $checkedOut = false;
/**
* @var \DateTime
*
* @ORM\Column(name="checked_out_at", type="datetime", nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $checkedOutAt;
/**
* @var boolean
*
* @ORM\Column(name="shipped", type="boolean")
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shipped = false;
/**
* @var /DateTime
*
* @ORM\Column(name="shipped_at", type="datetime", nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippedAt;
/**
* @var float
*
* @ORM\Column(name="rebate", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $rebate;
/**
* @var float
*
* @ORM\Column(name="rebate_converted", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $rebateConverted;
/**
* @var float
*
* @ORM\Column(name="subtotal", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $subtotal;
/**
* @var float
*
* @ORM\Column(name="subtotal_converted", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $subtotalConverted;
/**
* @var float
*
* @ORM\Column(name="tax", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $tax;
/**
* @var float
*
* @ORM\Column(name="tax_converted", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $taxConverted;
/**
* @var float
*
* @ORM\Column(name="total", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $total;
/**
* @var float
*
* @ORM\Column(name="total_converted", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $totalConverted;
/**
* @var float
*
* @ORM\Column(name="shipping_price", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $shippingPrice;
/**
* @var float
*
* @ORM\Column(name="shipping_price_converted", type="decimal", precision=18, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $shippingPriceConverted;
/**
* @var string
*
* @ORM\Column(name="invoice_country", type="string", length=2, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $invoiceCountry;
/**
* @var string
*
* @ORM\Column(name="invoice_state", type="string", length=30, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $invoiceState;
/**
* @var string
*
* @ORM\Column(name="invoice_city", type="string", length=70, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $invoiceCity;
/**
* @var string
*
* @ORM\Column(name="invoice_zip", type="string", length=30, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $invoiceZip;
/**
* @var string
*
* @ORM\Column(name="invoice_address", type="string", length=120, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $invoiceAddress;
/**
* @var string
*
* @ORM\Column(name="invoice_phone", type="string", length=120, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $invoicePhone;
/**
* @var boolean
*
* @ORM\Column(name="shipping_location_changed", type="boolean", nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippingLocationChanged = false;
/**
* @var string
*
* @ORM\Column(name="shipping_country", type="string", length=2, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippingCountry;
/**
* @var string
*
* @ORM\Column(name="shipping_state", type="string", length=30, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippingState;
/**
* @var string
*
* @ORM\Column(name="shipping_city", type="string", length=70, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippingCity;
/**
* @var string
*
* @ORM\Column(name="shipping_zip", type="string", length=30, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippingZip;
/**
* @var string
*
* @ORM\Column(name="shipping_address", type="string", length=120, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippingAddress;
/**
* @var string
*
* @ORM\Column(name="shipping_phone", type="string", length=120, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippingPhone;
/**
* @var bool
*
* @ORM\Column(name="shipping_dates_confirmed", type="boolean", options={"default":0})
*
* @Constraints\IsTrue(groups={"CheckOut"})
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shippingDatesConfirmed=0;
/**
* @var Shipping
*
* @ORM\ManyToOne(targetEntity="App\Entity\ECommerce\Shipping", inversedBy="carts")
* @ORM\JoinColumn(name="shipping", referencedColumnName="id")
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $shipping;
/**
* @var Currency
*
* @ORM\ManyToOne(targetEntity="App\Entity\ECommerce\Currency")
* @ORM\JoinColumn(name="currency", referencedColumnName="code")
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $currency;
/**
* @var float
*
* @ORM\Column(name="currency_rate", type="decimal", precision=12, scale=4, nullable=true)
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $currencyRate;
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="App\Entity\ECommerce\CartItem", mappedBy="cart", cascade={"persist"})
*
* @Constraints\Valid(groups={"CheckOut"})
*
* @JMS\Expose()
* @JMS\Groups({"cart_private", "view_cart"})
*/
private $items;
/**
* @var Invoice
*
* @ORM\OneToOne(targetEntity="App\Entity\ECommerce\Invoice", mappedBy="cart", cascade={"persist"})
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $invoice;
/**
* @var Client
*
* @ORM\ManyToOne(targetEntity="App\Entity\ECommerce\Client", inversedBy="carts")
* @ORM\JoinColumn(name="client", referencedColumnName="id")
*
* @JMS\Expose()
* @JMS\Groups({"cart_private"})
*/
private $client;
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="App\Entity\App\User", inversedBy="carts")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*
* @JMS\Expose()
* @JMS\Groups({"cart"})
*/
private $user;
/**
* Dates trait
* createdAt, updatedAt, IndexAt, syncedAt
*/
use DatesTrait {
DatesTrait::__construct as __DT_construct;
}
/**
* Constructor
*/
public function __construct(ECUserInterface $user)
{
$this->__DT_construct();
$this->items = new ArrayCollection();
$this->setCreatedAt();
if ($user) {
$this->user = $user;
$this->client = $user->getClient();
}
}
/**
* To String
*/
public function __toString(): string
{
return (string)$this->id;
}
/**
* Get id
*/
public function getId(): int
{
return $this->id ?? 0;
}
/**
* Set createdAt
*
* @param \DateTime $createdAt
*/
public function setCreatedAt($createdAt = null): self
{
$this->createdAt = $createdAt ?? new \DateTime();
return $this;
}
/**
* Get createdAt
*
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set updatedAt
*
* @param \DateTime $updatedAt
*/
public function setUpdatedAt($updatedAt = null): self
{
$this->updatedAt = $updatedAt ?? new \DateTime();
return $this;
}
/**
* Get updatedAt
*
* @return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Set payed
*
* @param boolean $payed
*/
public function setPayed($payed): self
{
$this->payed = $payed;
return $this;
}
public function isPayed(): bool
{
return $this->payed ?? false;
}
/**
* Get payed
*
* @return boolean
*/
public function getPayed()
{
return $this->payed ?? false;
}
/**
* Set subtotal
*
*
*/
public function setSubtotal(float $subtotal): self
{
$this->subtotal = $this->round($subtotal);
return $this;
}
/**
* Get subtotal
*
* @return float
*/
public function getSubtotal()
{
return $this->subtotal;
}
/**
* Set tax
*
*
*/
public function setTax(float $tax): self
{
$this->tax = $this->round($tax);
return $this;
}
/**
* Get tax
*
* @return string
*/
public function getTax()
{
return $this->tax;
}
/**
* Set shippingPrice
*
*
*/
public function setShippingPrice(float $shippingPrice): self
{
$this->shippingPrice = $this->round($shippingPrice);
return $this;
}
/**
* Get shippingPrice
*
* @return float
*/
public function getShippingPrice()
{
return $this->shippingPrice;
}
/**
* Set total
*
* @param float $total
*/
public function setTotal($total): self
{
$this->total = $total;
return $this;
}
/**
* Get total
*
* @return float
*/
public function getTotal()
{
return $this->total;
}
/**
* Set invoiceCountry
*
* @param string $invoiceCountry
*/
public function setInvoiceCountry($invoiceCountry): self
{
$this->invoiceCountry = $invoiceCountry;
return $this;
}
/**
* Get invoiceCountry
*
* @return string
*/
public function getInvoiceCountry()
{
return $this->invoiceCountry;
}
/**
* Set invoiceState
*
* @param string $invoiceState
*/
public function setInvoiceState($invoiceState): self
{
$this->invoiceState = $invoiceState;
return $this;
}
/**
* Get invoiceState
*
* @return string
*/
public function getInvoiceState()
{
return $this->invoiceState;
}
/**
* Set invoiceCity
*
* @param string $invoiceCity
*/
public function setInvoiceCity($invoiceCity): self
{
$this->invoiceCity = $invoiceCity;
return $this;
}
/**
* Get invoiceCity
*
* @return string
*/
public function getInvoiceCity()
{
return $this->invoiceCity;
}
/**
* Set invoiceZip
*
* @param string $invoiceZip
*/
public function setInvoiceZip($invoiceZip): self
{
$this->invoiceZip = $invoiceZip;
return $this;
}
/**
* Get invoiceZip
*
* @return string
*/
public function getInvoiceZip()
{
return $this->invoiceZip;
}
/**
* Set invoiceAddress
*
* @param string $invoiceAddress
*/
public function setInvoiceAddress($invoiceAddress): self
{
$this->invoiceAddress = $invoiceAddress;
return $this;
}
/**
* Get invoiceAddress
*
* @return string
*/
public function getInvoiceAddress()
{
return $this->invoiceAddress;
}
/**
* Set invoicePhone
*
* @param string $invoicePhone
*/
public function setInvoicePhone($invoicePhone): self
{
$this->invoicePhone = $invoicePhone;
return $this;
}
/**
* Get invoicePhone
*
* @return string
*/
public function getInvoicePhone()
{
return $this->invoicePhone;
}
/**
* Set shippingCountry
*
* @param string $shippingCountry
*/
public function setShippingCountry($shippingCountry): self
{
$this->shippingCountry = $shippingCountry;
return $this;
}
/**
* Get shippingCountry
*
* @return string
*/
public function getShippingCountry()
{
return $this->shippingCountry;
}
/**
* Set shippingState
*
* @param string $shippingState
*/
public function setShippingState($shippingState): self
{
$this->shippingState = $shippingState;
return $this;
}
/**
* Get shippingState
*
* @return string
*/
public function getShippingState()
{
return $this->shippingState;
}
/**
* Set shippingCity
*
* @param string $shippingCity
*/
public function setShippingCity($shippingCity): self
{
$this->shippingCity = $shippingCity;
return $this;
}
/**
* Get shippingCity
*
* @return string
*/
public function getShippingCity()
{
return $this->shippingCity;
}
/**
* Set shippingZip
*
* @param string $shippingZip
*/
public function setShippingZip($shippingZip): self
{
$this->shippingZip = $shippingZip;
return $this;
}
/**
* Get shippingZip
*
* @return string
*/
public function getShippingZip()
{
return $this->shippingZip;
}
/**
* Set shippingAddress
*
* @param string $shippingAddress
*/
public function setShippingAddress($shippingAddress): self
{
$this->shippingAddress = $shippingAddress;
return $this;
}
/**
* Get shippingAddress
*
* @return string
*/
public function getShippingAddress()
{
return $this->shippingAddress;
}
/**
* Set shippingPhone
*
* @param string $shippingPhone
*/
public function setShippingPhone($shippingPhone): self
{
$this->shippingPhone = $shippingPhone;
return $this;
}
/**
* Get shippingPhone
*
* @return string
*/
public function getShippingPhone()
{
return $this->shippingPhone;
}
/**
* Set shippingDatesConfirmed.
*
* @param bool $shippingDatesConfirmed
*/
public function setShippingDatesConfirmed($shippingDatesConfirmed): static
{
$this->shippingDatesConfirmed = $shippingDatesConfirmed;
return $this;
}
/**
* Get shippingDatesConfirmed.
*
* @return bool
*/
public function getShippingDatesConfirmed()
{
return $this->shippingDatesConfirmed;
}
/**
* Set shippingLocationChanged
*
*
*/
public function setShippingLocationChanged(bool $shippingLocationChanged): self
{
$this->shippingLocationChanged = $shippingLocationChanged;
return $this;
}
/**
* Get shippingLocationChanged
*
* @return boolean
*/
public function getShippingLocationChanged()
{
return $this->shippingLocationChanged;
}
/**
* Set currency
*
* @param string $currency
*/
public function setCurrency($currency): self
{
$this->currency = $currency;
return $this;
}
/**
* Get currency
*
* @return Currency
*/
public function getCurrency()
{
return $this->currency;
}
/**
* Set checkedOut
*
* @param boolean $checkedOut
*/
public function setCheckedOut($checkedOut): self
{
$this->checkedOut = $checkedOut;
return $this;
}
/**
* Get checkedOut
*/
public function getCheckedOut(): bool
{
return $this->isCheckedOut();
}
/**
* Get checkedOut
*/
public function isCheckedOut(): bool
{
return $this->checkedOut ?? false;
}
/**
* Set checkedOutAt
*
* @param \DateTime $checkedOutAt
*/
public function setCheckedOutAt($checkedOutAt=null): self
{
$this->checkedOutAt = $checkedOutAt ?? new \DateTime();
return $this;
}
/**
* Get checkedOutAt
*
* @return \DateTime
*/
public function getCheckedOutAt()
{
return $this->checkedOutAt;
}
/**
* Set shipped
*
* @param boolean $shipped
*/
public function setShipped($shipped): self
{
$this->shipped = $shipped;
return $this;
}
/**
* Get shipped
*/
public function getShipped(): bool
{
return $this->isShipped();
}
public function isShipped(): bool
{
return $this->shipped ?? false;
}
/**
* Set shippedAt
*
* @param \DateTime $shippedAt
*/
public function setShippedAt($shippedAt): self
{
$this->shippedAt = $shippedAt;
return $this;
}
/**
* Get shippedAt
*
* @return \DateTime
*/
public function getShippedAt()
{
return $this->shippedAt;
}
/**
* Add shipping
*
*
*/
public function setShipping(Shipping $shipping): self
{
$this->shipping = $shipping;
return $this;
}
/**
* Get shipping
*
* @return Shipping
*/
public function getShipping()
{
return $this->shipping;
}
/**
* Set currencyRate
*
* @param string $currencyRate
*/
public function setCurrencyRate($currencyRate): self
{
$this->currencyRate = $currencyRate;
return $this;
}
/**
* Get currencyRate
*
* @return string
*/
public function getCurrencyRate()
{
return $this->currencyRate;
}
/**
* Set subtotalConverted
*
*
*/
public function setSubtotalConverted(float $subtotalConverted): self
{
$this->subtotalConverted = $this->round($subtotalConverted);
return $this;
}
/**
* Get subtotalConverted
*
* @return float
*/
public function getSubtotalConverted()
{
return $this->subtotalConverted;
}
/**
* Set taxConverted
*
*
*/
public function setTaxConverted(float $taxConverted): self
{
$this->taxConverted = $this->round($taxConverted);
return $this;
}
/**
* Get taxConverted
*
* @return string
*/
public function getTaxConverted()
{
return $this->taxConverted;
}
/**
* Set totalConverted
*
*
*/
public function setTotalConverted(float $totalConverted): self
{
$this->totalConverted = $this->round($totalConverted);
return $this;
}
/**
* Get totalConverted
*
* @return string
*/
public function getTotalConverted()
{
return $this->totalConverted;
}
/**
* Set shippingPriceConverted
*
*
*/
public function setShippingPriceConverted(float $shippingPriceConverted): self
{
$this->shippingPriceConverted = $this->round($shippingPriceConverted);
return $this;
}
/**
* Get shippingPriceConverted
*
* @return string
*/
public function getShippingPriceConverted()
{
return $this->shippingPriceConverted;
}
/**
* Set rebate
*
*
*/
public function setRebate(float $rebate): self
{
$this->rebate = $rebate;
return $this;
}
/**
* Get rebate
*/
public function getRebate(): float
{
return (float) $this->rebate;
}
/**
* Set rebateConverted
*
*
*/
public function setRebateConverted(float $rebateConverted): self
{
$this->rebateConverted = $rebateConverted;
return $this;
}
/**
* Get rebateConverted
*/
public function getRebateConverted(): float
{
return (float) $this->rebateConverted;
}
/**
* Set invoice
*
* @param Invoice|null $invoice
*/
public function setInvoice(Invoice $invoice = null): self
{
$this->invoice = $invoice;
return $this;
}
/**
* Get invoice
*
* @return Invoice
*/
public function getInvoice(): ?Invoice
{
return $this->invoice;
}
/**
* Set client
*
*
*/
public function setClient(Client $client = null): self
{
$this->client = $client;
return $this;
}
/**
* Get client
*
* @return Client
*/
public function getClient()
{
return $this->client;
}
/**
* Set items
*
*
* @return $this
*/
public function setItems(array $items): static
{
$this->items = new ArrayCollection($items);
return $this;
}
/**
* Add item
*
*
*/
public function addItem(CartItem $item): self
{
$this->items[] = $item->setCart($this);
return $this;
}
/**
* Remove item
*/
public function removeItem(CartItem $item): void
{
$this->items->removeElement($item);
}
/**
* Get items
*/
public function getItems(): Collection
{
return $this->items;
}
public function hasItems(): bool
{
return !$this->items->isEmpty();
}
public function countItems(): int
{
if (!$this->hasItems()) {
return 0;
}
$items = array_map(fn(CartItem $item): ?int => $item->getQuantity(), $this->items->toArray());
return array_sum($items);
}
/**
* Set user
*
*
*/
public function setUser(User $user = null): self
{
$this->user = $user;
return $this;
}
/**
* Get user
*/
public function getUser(): User
{
return $this->user;
}
/**
* Round numbers
*
*
*/
private function round(float $amount): float
{
return round($amount, self::ROUNDING_PRECISION);
}
}