<?php
namespace App\Entity;
use App\Model\EntityTime;
use App\Repository\ProductRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
#[ORM\Entity(repositoryClass: ProductRepository::class)]
class Product extends EntityTime
{
#[Groups(['product:read'])]
#[ORM\Column(length: 255)]
private ?string $name = null;
#[ORM\ManyToOne(inversedBy: 'products')]
#[ORM\JoinColumn(nullable: false)]
private ?Category $category = null;
#[ORM\ManyToOne(inversedBy: 'products')]
#[ORM\JoinColumn(nullable: false)]
private ?Range $range = null;
#[ORM\ManyToOne(inversedBy: 'products')]
#[ORM\JoinColumn(nullable: false)]
#[Groups(['product:read'])]
private ?Serie $serie = null;
#[ORM\ManyToOne(inversedBy: 'products')]
#[ORM\JoinColumn(nullable: false)]
private ?Provider $provider = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $options = null;
#[Groups(['product:read'])]
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $description = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $required = null;
#[ORM\Column(length: 100, nullable: true)]
#[Groups(['product:read'])]
private ?string $referenceAFIMES = null;
#[ORM\Column(nullable: true)]
#[Groups(['product:read'])]
private ?int $providerSellingPrice = null;
#[ORM\Column(nullable: true)]
private ?int $providerDiscount = null;
#[ORM\Column(nullable: true)]
private ?int $recommendedMarginRate = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $comment = null;
#[ORM\Column(length: 20, nullable: true)]
private ?string $unit = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $additionalOptions = null;
#[Groups(['product:read'])]
private ?string $file;
#[ORM\OneToMany(mappedBy: 'product', targetEntity: ProductOption::class, orphanRemoval: true)]
#[Groups(['product:read'])]
private Collection $productOptions;
#[ORM\Column(length: 255, nullable: true)]
private ?string $pricingLastUpdate = null;
#[ORM\Column(nullable: true)]
private ?int $documentId = null;
public function __construct(
string $name = null,
Category $category = null,
Serie $serie = null,
Range $range = null,
Provider $provider = null
) {
parent::__construct();
$this->name = $name;
$this->category = $category;
$this->serie = $serie;
$this->range = $range;
$this->provider = $provider;
$this->productOptions = new ArrayCollection();
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): self
{
$this->category = $category;
return $this;
}
public function getRange(): ?Range
{
return $this->range;
}
public function setRange(?Range $range): self
{
$this->range = $range;
return $this;
}
public function getSerie(): ?Serie
{
return $this->serie;
}
public function setSerie(?Serie $serie): self
{
$this->serie = $serie;
return $this;
}
public function getProvider(): ?Provider
{
return $this->provider;
}
public function setProvider(?Provider $provider): self
{
$this->provider = $provider;
return $this;
}
public function getOptions(): ?string
{
return $this->options;
}
public function setOptions(?string $options): self
{
$this->options = $options;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getRequired(): ?string
{
return $this->required;
}
public function setRequired(?string $required): self
{
$this->required = $required;
return $this;
}
public function getReferenceAFIMES(): ?string
{
return $this->referenceAFIMES;
}
public function setReferenceAFIMES(?string $referenceAFIMES): self
{
$this->referenceAFIMES = $referenceAFIMES;
return $this;
}
public function getProviderSellingPrice(): int
{
return intval($this->providerSellingPrice);
}
public function setProviderSellingPrice(int|string|null $providerSellingPrice): self
{
if (is_string($providerSellingPrice)) {
$providerSellingPrice = trim($providerSellingPrice);
if (strtolower($providerSellingPrice) == 'offert') {
$providerSellingPrice = -1;
} elseif (strtolower($providerSellingPrice) == 'sur devis') {
$providerSellingPrice = -2;
} elseif (strtolower($providerSellingPrice) == 'x' || strtolower($providerSellingPrice) == '-') {
$providerSellingPrice = null;
} else {
$providerSellingPrice = str_replace('€', '', $providerSellingPrice);
$providerSellingPrice = str_replace(' ', '', $providerSellingPrice);
$providerSellingPrice = str_replace(' ', '', $providerSellingPrice);
$providerSellingPrice = str_replace(',', '.', $providerSellingPrice);
$providerSellingPrice = intval(floatval($providerSellingPrice) * 100);
}
}
$this->providerSellingPrice = $providerSellingPrice;
return $this;
}
public function getProviderDiscount(): ?int
{
return $this->providerDiscount;
}
public function setProviderDiscount(int|string|null $providerDiscount): self
{
if (is_string($providerDiscount)) {
$providerDiscount = str_replace('%', '', $providerDiscount);
$providerDiscount = str_replace(',', '.', $providerDiscount);
$providerDiscount = trim($providerDiscount);
$providerDiscount = intval($providerDiscount);
}
$this->providerDiscount = $providerDiscount;
return $this;
}
public function getRecommendedMarginRate(): ?int
{
return $this->recommendedMarginRate;
}
public function setRecommendedMarginRate(int|string|null $recommendedMarginRate): self
{
if (is_string($recommendedMarginRate)) {
$recommendedMarginRate = str_replace('%', '', $recommendedMarginRate);
$recommendedMarginRate = str_replace(',', '.', $recommendedMarginRate);
$recommendedMarginRate = trim($recommendedMarginRate);
$recommendedMarginRate = intval($recommendedMarginRate);
}
$this->recommendedMarginRate = $recommendedMarginRate;
return $this;
}
public function getComment(): ?string
{
return $this->comment;
}
public function setComment(?string $comment): self
{
$this->comment = $comment;
return $this;
}
public function getUnit(): ?string
{
return $this->unit;
}
public function setUnit(?string $unit): self
{
$this->unit = $unit;
return $this;
}
public function getAdditionalOptions(): ?string
{
return $this->additionalOptions;
}
public function setAdditionalOptions(?string $additionalOptions): self
{
$this->additionalOptions = $additionalOptions;
return $this;
}
/**
* @return Collection<int, ProductOption>
*/
public function getProductOptions(): Collection
{
return $this->productOptions;
}
public function addProductOption(ProductOption $productOption): self
{
if (!$this->productOptions->contains($productOption)) {
$this->productOptions->add($productOption);
$productOption->setProduct($this);
}
return $this;
}
public function removeProductOption(ProductOption $productOption): self
{
if ($this->productOptions->removeElement($productOption)) {
// set the owning side to null (unless already changed)
if ($productOption->getProduct() === $this) {
$productOption->setProduct(null);
}
}
return $this;
}
public function getProductOptionByName(string $name): ProductOption|bool
{
return $this->productOptions
->filter(fn (ProductOption $option) => $option->getName() == $name)
->first();
}
public function setFile(?string $file): self
{
$this->file = $file;
return $this;
}
public function getFile(): ?string
{
return $this->file;
}
public function getPricingLastUpdate(): ?string
{
return $this->pricingLastUpdate;
}
public function setPricingLastUpdate(?string $pricingLastUpdate): self
{
$this->pricingLastUpdate = $pricingLastUpdate;
return $this;
}
public function getPrice(bool $discount = true): int
{
if(!$discount) {
return $this->getProviderSellingPrice();
}
$buyPrice = ($this->getProviderSellingPrice() / 100) * (1 - ($this->getProviderDiscount()/100));
return ceil(($buyPrice / (1 - ($this->getRecommendedMarginRate()/ 100))) / 10) * 10;
}
public function getFinalPrice(): float
{
$salePriceInitial = ceil((($this->getProviderSellingPrice() / 100) / (1 - ($this->getRecommendedMarginRate()/ 100))) / 10) * 10;
return ($salePriceInitial * (1 + ($this->getRecommendedMarginRate() / 100)));
}
public function getDocumentId(): ?int
{
return $this->documentId;
}
public function setDocumentId(?int $documentId): self
{
$this->documentId = $documentId;
return $this;
}
public function getOptionValueByName(string $name): mixed
{
$option = $this->getProductOptionByName($name);
return $option ? $option->getValue() : null;
}
}