<?php
namespace App\Entity;
use App\Entity\Enum\RegistrationStatus;
use App\Entity\Traits\Identifiable;
use App\Repository\ItemVariationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ItemVariationRepository::class)]
class ItemVariation
{
use Identifiable;
#[ORM\Column(type: 'string', length: 100, nullable: true)]
private $name;
#[ORM\Column(type: 'smallint', nullable: true)]
private $price;
#[ORM\Column(type: 'boolean')]
private $isDisplayed = true;
#[ORM\Column(type: 'boolean')]
private $hasStock = false;
#[ORM\ManyToOne(targetEntity: Item::class, inversedBy: 'variations')]
#[ORM\JoinColumn(nullable: false)]
private $item;
#[ORM\ManyToOne(targetEntity: ItemSize::class, inversedBy: 'itemVariations')]
private $size;
#[ORM\OneToOne(targetEntity: FileItem::class, cascade: ['persist', 'remove'])]
private $file;
#[ORM\OneToMany(mappedBy: 'purchaseItem', targetEntity: CartItemPurchase::class)]
private $purchases;
#[ORM\OneToMany(mappedBy: 'rentalItem', targetEntity: CartItemRental::class)]
private $rentals;
#[ORM\OneToMany(mappedBy: 'variation', targetEntity: ItemVariationSection::class, orphanRemoval: true, cascade: ['persist'])]
private $itemVariationSections;
public function __construct()
{
$this->purchases = new ArrayCollection();
$this->rentals = new ArrayCollection();
$this->itemVariationSections = new ArrayCollection();
}
public function getName(bool $size = true): ?string
{
$name = $this->name ?? $this->getItem()?->getName();
if ($size) {
if ($this->getSize()) {
$name = sprintf('%s - %s', $name, $this->getSize()->getName());
} else {
$name = sprintf('%s - Taille unique', $name);
}
}
return $name;
}
public function setName(?string $name): self
{
$this->name = $name;
return $this;
}
public function getPrice(): ?int
{
return $this->price ?? $this->getItem()?->getPrice();
}
public function setPrice(?int $price): self
{
$this->price = $price;
return $this;
}
public function getIsDisplayed(): ?bool
{
return $this->getItem()?->getIsDisplayed() ? $this->isDisplayed : false;
}
public function setIsDisplayed(bool $isDisplayed): self
{
$this->isDisplayed = $isDisplayed;
return $this;
}
public function getHasStock(): ?bool
{
return $this->hasStock;
}
public function setHasStock(bool $hasStock): self
{
$this->hasStock = $hasStock;
return $this;
}
public function getItem(): ?Item
{
return $this->item;
}
public function setItem(?Item $item): self
{
$this->item = $item;
return $this;
}
public function getSize(): ?ItemSize
{
return $this->size;
}
public function setSize(?ItemSize $size): self
{
$this->size = $size;
return $this;
}
public function getFile(): ?FileItem
{
return $this->file ?? $this->getItem()?->getFile();
}
public function setFile(?FileItem $file): self
{
$this->file = $file;
return $this;
}
/**
* @return Collection<int, CartItemPurchase>
*/
public function getPurchases(): Collection
{
return $this->purchases;
}
public function addPurchase(CartItemPurchase $purchase): self
{
if (!$this->purchases->contains($purchase)) {
$this->purchases[] = $purchase;
$purchase->setPurchaseItem($this);
}
return $this;
}
public function removePurchase(CartItemPurchase $purchase): self
{
if ($this->purchases->removeElement($purchase)) {
// set the owning side to null (unless already changed)
if ($purchase->getPurchaseItem() === $this) {
$purchase->setPurchaseItem(null);
}
}
return $this;
}
/**
* @return Collection<int, CartItemRental>
*/
public function getRentals(): Collection
{
return $this->rentals;
}
public function addRental(CartItemRental $rental): self
{
if (!$this->rentals->contains($rental)) {
$this->rentals[] = $rental;
$rental->setRentalItem($this);
}
return $this;
}
public function removeRental(CartItemRental $rental): self
{
if ($this->rentals->removeElement($rental)) {
// set the owning side to null (unless already changed)
if ($rental->getRentalItem() === $this) {
$rental->setRentalItem(null);
}
}
return $this;
}
/**
* @return Collection<int, ItemVariationSection>
*/
public function getItemVariationSections(): Collection
{
return $this->itemVariationSections;
}
public function addItemVariationSection(ItemVariationSection $itemVariationSection): self
{
if (!$this->itemVariationSections->contains($itemVariationSection)) {
$this->itemVariationSections[] = $itemVariationSection;
$itemVariationSection->setVariation($this);
}
return $this;
}
public function removeItemVariationSection(ItemVariationSection $itemVariationSection): self
{
if ($this->itemVariationSections->removeElement($itemVariationSection)) {
// set the owning side to null (unless already changed)
if ($itemVariationSection->getVariation() === $this) {
$itemVariationSection->setVariation(null);
}
}
return $this;
}
public function getRemainingStock(?Section $section = null): ?int
{
if (!$this->hasStock) {
return null;
}
$remaining = 0;
foreach ($this->getItemVariationSections() as $itemVariationSection) {
if ($section && $section !== $itemVariationSection->getSection()) {
continue;
}
foreach ($itemVariationSection->getStocks() as $stock) {
$remaining += $stock->getStock();
}
}
$usages = array_merge($this->getPurchases()->toArray(), $this->getRentals()->toArray());
foreach ($usages as $purchase) {
$registration = $purchase->getCart()->getOrder()->getRegistration();
if ($section && $registration->getSeason()->getSection() !== $section) {
continue;
}
if (in_array($registration->getStatus(), RegistrationStatus::VALID_VALUES, true)) {
$remaining--;
}
}
return $remaining;
}
/**
* @return array<int, Section>
*/
public function getSections(): array
{
$sections = [];
foreach ($this->getItemVariationSections() as $itemVariationSection) {
$sections[] = $itemVariationSection->getSection();
}
return $sections;
}
}