<?php
namespace App\Entity\Product;
use App\Validator\Constraints as AppAssert;
use App\Entity\Customer;
use App\Entity\Supplier;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\{Column,
DiscriminatorColumn,
DiscriminatorMap,
Entity,
GeneratedValue,
HasLifecycleCallbacks,
Id,
InheritanceType,
JoinColumn,
ManyToMany,
ManyToOne,
PrePersist,
PreUpdate,
Table};
use Doctrine\ORM\Mapping as ORM;
use Exception;
use JMS\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints\{NotBlank};
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Product
*
* @package App\Entity
* @Table(name="malys_product")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="type", type="string")
* @AppAssert\Product()
* @DiscriminatorMap({"guest" = "GuestProduct", "confirmed" = "ConfirmedProduct"})
* @Entity()
* @HasLifecycleCallbacks()
*/
abstract class Product
{
public const TYPES = [
self::TYPE_CONFIRMED,
self::TYPE_GUEST,
];
public const TYPE_CONFIRMED = 'confirmed';
public const TYPE_GUEST = 'guest';
/**
* @var integer
*
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="AUTO")
* @Groups({"api"})
*/
protected $id;
/**
* @var string
*
* @Column(name="code", type="string", length=255, nullable=true)
* @Assert\NotBlank(message="Indiquez le code du produit", groups={"invoiceEdit"})
*/
protected $code;
/**
* @var Supplier
*
* @ManyToOne(targetEntity="App\Entity\Supplier", inversedBy="products")
* @JoinColumn(name="supplier_id", referencedColumnName="id")
* @NotBlank()
*/
protected $supplier;
/**
* @var string
*
* @Column(name="name", type="string", length=255, nullable=false)
* @NotBlank(message="Indiquez le nom du produit")
* @Groups({"api"})
*/
protected $name;
/**
* @var boolean
*
* @Column(name="enabled", type="boolean", )
* @Groups({"api"})
*/
protected $enabled = true;
/**
* @var DateTime
*
* @Column(name="createdAt", type="datetime", nullable=false)
* @Groups({"api"})
*/
protected $createdAt;
/**
* @var DateTime
*
* @Column(name="updatedAt", type="datetime", nullable=true)
* @Groups({"api"})
*/
protected $updatedAt;
/**
* @ManyToMany(targetEntity="App\Entity\Customer", inversedBy="favoritesProducts", fetch="LAZY")
* @ORM\JoinTable(name="malys_customers_favorites_products")
*/
protected $customers;
public function __construct()
{
$this->customers = new ArrayCollection();
}
abstract public function getType();
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return string
*/
public function getCode()
{
return $this->code;
}
/**
* @param string $code
*/
public function setCode($code)
{
$this->code = $code;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return mixed
*/
public function getSupplier()
{
return $this->supplier;
}
/**
* @param mixed $supplier
*/
public function setSupplier($supplier)
{
$this->supplier = $supplier;
}
/**
* @return bool
*/
public function isEnabled()
{
return $this->enabled;
}
/**
* @param bool $enabled
*/
public function setEnabled($enabled)
{
$this->enabled = $enabled;
}
/**
* @return DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @return Product
* @throws Exception
* @PrePersist
*/
public function setCreatedAt()
{
$this->createdAt = new DateTime();
$this->updatedAt = new DateTime();
return $this;
}
/**
* @return DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* @return ArrayCollection
*/
public function getCustomers()
{
return $this->customers;
}
/**
* @param ArrayCollection $customers
*/
public function setCustomers($customers)
{
$this->customers = $customers;
}
/**
* @param Customer $customer
*/
public function addCustomer($customer)
{
if (!$this->customers->contains($customer)) {
$this->customers->add($customer);
}
}
/**
* @param Customer $customer
*/
public function removeCustomer($customer)
{
if ($this->customers->contains($customer)) {
$this->customers->removeElement($customer);
$customer->removeFavoriteProduct($this);
}
}
public function addOrRemoveInCustomerFav(Customer $customer)
{
if ($this->customers->contains($customer)) {
$this->customers->removeElement($customer);
return false;
} else {
$this->customers->add($customer);
return true;
}
}
/**
* Set updatedAt
*
* @return Product
* @throws Exception
* @PreUpdate
*/
public function setUpdatedAt()
{
if ($this->autoUpdateDate === false) {
return $this;
}
$this->updatedAt = new DateTime();
return $this;
}
public function __call($name, $arguments)
{
if (method_exists(self::class, $name)) {
return $this->$name;
}
return null;
}
public function __get($name)
{
$methods = [
'get' . $name,
'get' . ucfirst($name),
'is' . $name,
'is' . ucfirst($name)
];
foreach ($methods as $method) {
if (method_exists(self::class, $method)) {
return $this->$method;
}
}
return null;
}
}