<?php
namespace App\Entity;
use App\Exception\InvalidArgumentException;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* @ORM\Entity(
* repositoryClass="App\Repository\PriceRepository"
* )
* @ORM\Table(
* name="price",
* options={"collate"="utf8_swedish_ci"}
* )
* @ORM\HasLifecycleCallbacks
*/
class Price implements EntityInterface
{
/**
* @ORM\Id
* @ORM\Column(
* type="integer"
* )
* @ORM\GeneratedValue(
* strategy="AUTO"
* )
*
* @var int|null
*/
protected ?int $id = null;
/**
* @ORM\Column(
* type="integer"
* )
* @Assert\NotNull
* @Assert\Range(
* min=0
* )
*
* @var int
*/
protected int $price;
/**
* @ORM\ManyToOne(
* targetEntity="PriceList",
* inversedBy="prices"
* )
* @ORM\JoinColumn(
* name="price_list_id",
* referencedColumnName="id",
* onDelete="cascade"
* )
*
* @Assert\NotNull
*
* @var PriceList
*/
protected PriceList $priceList;
/**
* @ORM\ManyToOne(
* targetEntity="Product",
* inversedBy="prices",
* cascade={"persist"}
* )
* @ORM\JoinColumn(
* name="product_id",
* referencedColumnName="id",
* onDelete="cascade"
* )
*
* @var Product|null
*/
protected ?Product $product = null;
/**
* @ORM\ManyToOne(
* targetEntity="ProductVersion",
* inversedBy="prices",
* cascade={"persist"}
* )
* @ORM\JoinColumn(
* name="product_version_id",
* referencedColumnName="id",
* onDelete="cascade"
* )
*
* @var ProductVersion|null
*/
protected ?ProductVersion $productVersion = null;
/**
* @param PriceList $priceList
* @param PricedInterface $product
* @param int $price
*/
public function __construct(PriceList $priceList, PricedInterface $product, int $price)
{
$this->priceList = $priceList;
if ($product instanceof Product) {
$this->setProduct($product);
} elseif ($product instanceof ProductVersion) {
$this->setProductVersion($product);
}
$this->setPrice($price);
}
/**
* @return string
*/
public function __toString(): string
{
return $this->getFormatted();
}
/**
* @return string
*/
public function getFormatted(): string
{
return number_format($this->price / 100, 2, ',', ' ') . ' ' . $this->priceList->getPriceGroup()->getCurrency();
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* @return int
*/
public function getPrice(): int
{
return $this->price;
}
/**
* @return PriceList
*/
public function getPriceList(): PriceList
{
return $this->priceList;
}
/**
* @return Product|null
*/
public function getProduct(): ?Product
{
return $this->product;
}
/**
* @return ProductVersion|null
*/
public function getProductVersion(): ?ProductVersion
{
return $this->productVersion;
}
/**
* @param int $price
*/
public function setPrice(int $price): void
{
$this->price = $price;
}
/**
* @param PriceList $priceList
*/
public function setPriceList(PriceList $priceList): void
{
$this->priceList = $priceList;
}
/**
* @param Product $product
*/
public function setProduct(Product $product): void
{
$this->product = $product;
$this->productVersion = null;
}
/**
* @param ProductVersion $productVersion
*/
public function setProductVersion(ProductVersion $productVersion): void
{
$this->productVersion = $productVersion;
$this->product = null;
}
/**
* @Assert\Callback
*
* @param ExecutionContextInterface $context
*/
public function validate(ExecutionContextInterface $context): void
{
if ($this->product === null && $this->productVersion === null) {
$context->buildViolation('error.product.none')
->atPath('product')
->addViolation();
} elseif ($this->product !== null && $this->productVersion !== null) {
$context->buildViolation('error.product.both')
->atPath('product')
->addViolation();
}
}
}