<?php
namespace App\Entity;
use App\Traits\Activeable;
use App\Traits\Creatable;
use App\Traits\Deleteable;
use App\Traits\Sortable;
use App\Traits\Updateable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @ORM\Table(name="`product`")
* @Gedmo\SoftDeleteable(fieldName="deletedAt")
* @UniqueEntity(fields={"constName", "reference"})
*/
class Product
{
const BUSINESS_CARD = 'BUSINESS_CARD';
const DIGITAL_MENU = 'DIGITAL_MENU';
const ENVELOPE = 'ENVELOPE';
const FLYER = 'FLYER';
const FOLDED_LOYALTY_CARD = 'FOLDED_LOYALTY_CARD';
const HEADED_PAPER = 'HEADED_PAPER';
const LEAFLET = 'LEAFLET';
const MENU_PEL = 'MENU_PEL';
const MENU_PLA = 'MENU_PLA';
const QRCODE_STICK_BOARD = 'QRCODE_STICK_BOARD';
const SOCIAL_NETWORK = 'SOCIAL_NETWORK';
const STANDARD_LOYALTY_CARD = 'STANDARD_LOYALTY_CARD';
const TABLE_SET_PAPER = 'TABLE_SET_PAPER';
const TABLE_SET_PLASTIC = 'TABLE_SET_PLASTIC';
const MENU_HOLDER_PEL = 'MENU_HOLDER_PEL';
const MENU_HOLDER_POLY_COLOR = 'MENU_HOLDER_POLY_COLOR';
const MENU_HOLDER_POLY_TRANSPARENT = 'MENU_HOLDER_POLY_TRANSPARENT';
const MENU_HOLDER_TEXTURED = 'MENU_HOLDER_TEXTURED';
const SHEET_PROTECTOR = 'SHEET_PROTECTOR';
const BACKGROUND_SHEET = 'BACKGROUND_SHEET';
const INNER_SHEET = 'INNER_SHEET';
const MENU_PEL__13 = 'MENU_PEL__13';
const MENU_PEL__A3 = 'MENU_PEL__A3';
const MENU_PEL__A4 = 'MENU_PEL__A4';
const MENU_PEL__A5 = 'MENU_PEL__A5';
const MENU_PEL__A6 = 'MENU_PEL__A6';
const MENU_PEL__CARRE = 'MENU_PEL__CARRE';
use Creatable, Updateable, Deleteable, Activeable, Sortable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private ?int $id = null;
/**
* @var ?string
*
* @ORM\Column(type="string", nullable=true, unique=true)
*/
private ?string $constName = null;
/**
* @var ?string
*
* @ORM\Column(type="string", nullable=true, unique=true)
*/
private ?string $printComConstName = null;
/**
* @var string
*
* @ORM\Column(name="reference", type="string", unique=true)
*/
private string $reference;
/**
* @var ?string
*
* @ORM\Column(name="carrier_algorithm", type="text", nullable=true)
*/
private ?string $carrierAlgorithm = null;
/**
* @var boolean
*
* @ORM\Column(name="builder_access", type="boolean")
*/
private bool $builderAccess;
/**
* @ORM\ManyToOne(targetEntity="Tax")
*/
private ?Tax $tax = null;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\File")
*/
private ?File $file = null;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Category", inversedBy="products")
*/
private Collection $categories;
/**
* @ORM\ManyToMany(targetEntity="ModelCategory")
* @ORM\OrderBy({"position" = "ASC"})
*/
private Collection $modelCategories;
/**
* @ORM\ManyToMany(targetEntity="Folder")
*/
private Collection $folders;
/**
* @ORM\ManyToMany(targetEntity="Attribut")
*/
private Collection $attributs;
/**
* @ORM\OneToMany(targetEntity="ProductStep", mappedBy="product")
* @ORM\OrderBy({"position" = "ASC"})
*/
private Collection $productSteps;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProductFeature", mappedBy="product", cascade={"persist"})
* @ORM\OrderBy({"position" = "ASC"})
*/
private Collection $productFeatures;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProductPrice", mappedBy="product")
* @ORM\OrderBy({"step" = "ASC"})
*/
private Collection $productPrices;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProductPriceMockup", mappedBy="product")
*/
private Collection $productPriceMockups;
/**
* @ORM\OneToMany(targetEntity="ProductMenuMaker", mappedBy="product")
*/
private Collection $productMenuMakers;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProductTranslation", mappedBy="product", cascade={"remove", "persist"})
*/
private Collection $productTranslations;
/**
* @var array
*/
private array $categoryPaths;
/**
* @ORM\OneToMany(targetEntity="App\Entity\AssociatedProduct", mappedBy="product", cascade={"remove", "persist"})
* @ORM\OrderBy({"position" = "ASC"})
*/
private Collection $associatedProducts;
/**
* @var ?string
*
* @ORM\Column(name="url_name", type="string", unique=true, nullable=true)
*/
private ?string $urlName = null;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProductPicture", mappedBy="product")
* @ORM\OrderBy({"position" = "ASC"})
*/
private Collection $productPictures;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProductReview", mappedBy="product")
*/
private Collection $productReviews;
public function __construct()
{
$this->active = false;
$this->modelCategories = new ArrayCollection();
$this->folders = new ArrayCollection();
$this->attributs = new ArrayCollection();
$this->categoryPaths = [];
$this->productSteps = new ArrayCollection();
$this->categories = new ArrayCollection();
$this->productFeatures = new ArrayCollection();
$this->productPrices = new ArrayCollection();
$this->productPictures = new ArrayCollection();
$this->productPriceMockups = new ArrayCollection();
$this->productMenuMakers = new ArrayCollection();
$this->productTranslations = new ArrayCollection();
$this->associatedProducts = new ArrayCollection();
$this->builderAccess = false;
}
public function __clone()
{
$this->id = null;
$this->reference .= '-copie';
$this->active = false;
$this->modelCategories = new ArrayCollection();
$this->attributs = new ArrayCollection();
$this->productSteps = new ArrayCollection();
$this->categories = new ArrayCollection();
$this->productFeatures = new ArrayCollection();
$this->productPrices = new ArrayCollection();
$this->productMenuMakers = new ArrayCollection();
$this->productTranslations = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getConstName(): ?string
{
return $this->constName;
}
public function setConstName(?string $constName): self
{
$this->constName = $constName;
return $this;
}
public function getPrintComConstName(): ?string
{
return $this->printComConstName;
}
public function setPrintComConstName(?string $printComConstName): self
{
$this->printComConstName = $printComConstName;
return $this;
}
public function getReference(): ?string
{
return $this->reference;
}
public function setReference(string $reference): self
{
$this->reference = $reference;
return $this;
}
public function getCarrierAlgorithm(): ?string
{
return $this->carrierAlgorithm;
}
public function setCarrierAlgorithm(?string $carrierAlgorithm): self
{
$this->carrierAlgorithm = $carrierAlgorithm;
return $this;
}
public function getTax(): ?Tax
{
return $this->tax;
}
public function setTax(?Tax $tax): self
{
$this->tax = $tax;
return $this;
}
public function getFile(): ?File
{
return $this->file;
}
public function setFile(?File $file): self
{
$this->file = $file;
return $this;
}
/**
* @return Collection|Category[]
*/
public function getCategories(): Collection|array
{
return $this->categories;
}
public function addCategory(Category $category): self
{
if (!$this->categories->contains($category)) {
$this->categories[] = $category;
}
return $this;
}
public function removeCategory(Category $category): self
{
if ($this->categories->contains($category)) {
$this->categories->removeElement($category);
}
return $this;
}
/**
* @return Collection|ModelCategory[]
*/
public function getModelCategories(): Collection|array
{
return $this->modelCategories;
}
public function addModelCategory(ModelCategory $modelCategory): self
{
if (!$this->modelCategories->contains($modelCategory)) {
$this->modelCategories[] = $modelCategory;
}
return $this;
}
public function removeModelCategory(ModelCategory $modelCategory): self
{
if ($this->modelCategories->contains($modelCategory)) {
$this->modelCategories->removeElement($modelCategory);
}
return $this;
}
/**
* @return Collection|Folder[]
*/
public function getFolders(): array|Collection
{
return $this->folders;
}
public function addFolder(Folder $folder): self
{
if (!$this->folders->contains($folder)) {
$this->folders[] = $folder;
}
return $this;
}
public function removeFolder(Folder $folder): self
{
$this->folders->removeElement($folder);
return $this;
}
/**
* @return Collection|Attribut[]
*/
public function getAttributs(): Collection|array
{
return $this->attributs;
}
public function addAttribut(Attribut $attribut): self
{
if (!$this->attributs->contains($attribut)) {
$this->attributs[] = $attribut;
}
return $this;
}
public function removeAttribut(Attribut $attribut): self
{
if ($this->attributs->contains($attribut)) {
$this->attributs->removeElement($attribut);
}
return $this;
}
/**
* @return Collection|ProductStep[]
*/
public function getProductSteps(): Collection|array
{
return $this->productSteps;
}
public function addProductStep(ProductStep $productStep): self
{
if (!$this->productSteps->contains($productStep)) {
$this->productSteps[] = $productStep;
$productStep->setProduct($this);
}
return $this;
}
public function removeProductStep(ProductStep $productStep): self
{
if ($this->productSteps->contains($productStep)) {
$this->productSteps->removeElement($productStep);
// set the owning side to null (unless already changed)
if ($productStep->getProduct() === $this) {
$productStep->setProduct(null);
}
}
return $this;
}
/**
* @return Collection|ProductFeature[]
*/
public function getProductFeatures(): Collection|array
{
return $this->productFeatures;
}
public function addProductFeature(ProductFeature $productFeature): self
{
if (!$this->productFeatures->contains($productFeature)) {
$this->productFeatures[] = $productFeature;
$productFeature->setProduct($this);
}
return $this;
}
public function removeProductFeature(ProductFeature $productFeature): self
{
if ($this->productFeatures->contains($productFeature)) {
$this->productFeatures->removeElement($productFeature);
// set the owning side to null (unless already changed)
if ($productFeature->getProduct() === $this) {
$productFeature->setProduct(null);
}
}
return $this;
}
/**
* @return Collection|ProductPrice[]
*/
public function getProductPrices(): array|Collection
{
return $this->productPrices;
}
public function addProductPrice(ProductPrice $productPrice): self
{
if (!$this->productPrices->contains($productPrice)) {
$this->productPrices[] = $productPrice;
$productPrice->setProduct($this);
}
return $this;
}
public function removeProductPrice(ProductPrice $productPrice): self
{
if ($this->productPrices->contains($productPrice)) {
$this->productPrices->removeElement($productPrice);
// set the owning side to null (unless already changed)
if ($productPrice->getProduct() === $this) {
$productPrice->setProduct(null);
}
}
return $this;
}
/**
* @return Collection|ProductPriceMockup[]
*/
public function getProductPriceMockups(): Collection|array
{
return $this->productPriceMockups;
}
public function addProductPriceMockup(ProductPriceMockup $productPriceMockup): self
{
if (!$this->productPriceMockups->contains($productPriceMockup)) {
$this->productPriceMockups[] = $productPriceMockup;
$productPriceMockup->setProduct($this);
}
return $this;
}
public function removeProductPriceMockup(ProductPriceMockup $productPriceMockup): self
{
if ($this->productPriceMockups->contains($productPriceMockup)) {
$this->productPriceMockups->removeElement($productPriceMockup);
// set the owning side to null (unless already changed)
if ($productPriceMockup->getProduct() === $this) {
$productPriceMockup->setProduct(null);
}
}
return $this;
}
/**
* @return Collection|ProductMenuMaker[]
*/
public function getProductMenuMakers(): Collection|array
{
return $this->productMenuMakers;
}
public function addProductMenuMaker(ProductMenuMaker $productMenuMaker): self
{
if (!$this->productMenuMakers->contains($productMenuMaker)) {
$this->productMenuMakers[] = $productMenuMaker;
$productMenuMaker->setProduct($this);
}
return $this;
}
public function removeProductMenuMaker(ProductMenuMaker $productMenuMaker): self
{
if ($this->productMenuMakers->contains($productMenuMaker)) {
$this->productMenuMakers->removeElement($productMenuMaker);
// set the owning side to null (unless already changed)
if ($productMenuMaker->getProduct() === $this) {
$productMenuMaker->setProduct(null);
}
}
return $this;
}
/**
* @return Collection|ProductTranslation[]
*/
public function getProductTranslations(): array|Collection
{
return $this->productTranslations;
}
public function addProductTranslation(ProductTranslation $productTranslation): self
{
if (!$this->productTranslations->contains($productTranslation)) {
$this->productTranslations[] = $productTranslation;
$productTranslation->setProduct($this);
}
return $this;
}
public function removeProductTranslation(ProductTranslation $productTranslation): self
{
if ($this->productTranslations->contains($productTranslation)) {
$this->productTranslations->removeElement($productTranslation);
// set the owning side to null (unless already changed)
if ($productTranslation->getProduct() === $this) {
$productTranslation->setProduct(null);
}
}
return $this;
}
public function setCategoryPaths(array $path)
{
$this->categoryPaths = $path;
}
public function getCategoryPaths()
{
return $this->categoryPaths;
}
/**
* @return Collection<int, AssociatedProduct>
*/
public function getAssociatedProducts(): Collection
{
return $this->associatedProducts;
}
public function addAssociatedProduct(AssociatedProduct $associatedProduct): self
{
if (!$this->associatedProducts->contains($associatedProduct)) {
$this->associatedProducts[] = $associatedProduct;
$associatedProduct->setProduct($this);
}
return $this;
}
public function removeAssociatedProduct(AssociatedProduct $associatedProduct): self
{
if ($this->associatedProducts->removeElement($associatedProduct)) {
// set the owning side to null (unless already changed)
if ($associatedProduct->getProduct() === $this) {
$associatedProduct->setProduct(null);
}
}
return $this;
}
/**
* @return Collection|Attribut[]
*/
public function getAttributValids(): Collection|array
{
$attributs = new ArrayCollection();
/** @var Attribut $attribut */
foreach ($this->attributs as $attribut) {
if ($attribut->getAttributValueActives()->count() > 0) {
if (!$attributs->contains($attribut)) {
$attributs->add($attribut);
}
}
}
return $attributs;
}
/**
* @return bool
*/
public function hasProductPriceActive()
{
$productPriceActive = false;
/** @var ProductPrice $productPrice */
foreach ($this->productPrices as $productPrice) {
if ($productPrice->isActive()) {
$productPriceActive = true;
break;
}
}
return $productPriceActive;
}
/**
* @return bool
*/
public function isCustomizable()
{
$isCustomizable = false;
/** @var ProductFeature $productFeature */
foreach ($this->productFeatures as $productFeature) {
if ($productFeature->getFeature()->getFeatureFamily()->getConstName() == FeatureFamily::CUSTOMIZABLE) {
$isCustomizable = true;
break;
}
}
return $isCustomizable;
}
/**
* @return bool
*/
public function isPrintable()
{
$isPrintable = false;
/** @var ProductFeature $productFeature */
foreach ($this->productFeatures as $productFeature) {
if ($productFeature->getFeature()->getFeatureFamily()->getConstName() == FeatureFamily::PRINTABLE) {
$isPrintable = true;
break;
}
}
return $isPrintable;
}
/**
* @return bool
*/
public function isClassic()
{
$isCustomizable = false;
/** @var ProductFeature $productFeature */
foreach ($this->productFeatures as $productFeature) {
if ($productFeature->getFeature()->getFeatureFamily()->getConstName() == FeatureFamily::CLASSIC) {
$isCustomizable = true;
break;
}
}
return $isCustomizable;
}
/**
* @return bool
*/
public function isDeliverable()
{
$isDeliverable = false;
/** @var ProductStep $productStep */
foreach ($this->productSteps as $productStep) {
if ($productStep->getStep()->getConstName() == Step::DELIVERY) {
$isDeliverable = true;
break;
}
}
return $isDeliverable;
}
/**
* @return ProductFeature[]
*/
public function getProductFeaturesIndexed()
{
$productFeatures = [];
foreach ($this->getProductFeatures() as $productFeature) {
$productFeatures[$productFeature->getFeature()->getId()] = $productFeature;
}
return $productFeatures;
}
/**
* @return ProductPrice|mixed|null
*/
public function getMinProductPrice()
{
$minProductPrice = null;
foreach ($this->getProductPrices() as $productPrice) {
if (is_null($minProductPrice)) {
$minProductPrice = $productPrice;
}
if ($productPrice->getPriceHt() < $minProductPrice->getPriceHt()) {
$minProductPrice = $productPrice;
}
}
return $minProductPrice;
}
/**
* @return bool
*/
public function isCommandable(): bool
{
if (!$this->isActive()) {
return false;
}
if ($this->isClassic() or $this->isPrintable()) {
if (!$this->hasProductPriceActive()) {
return false;
}
}
if ($this->isCustomizable()) {
if ($this->getProductMenuMakers()->count() == 0) {
return false;
}
// $haveModelCategory = false;
//
// if ($this->getModelCategories()->count() > 0) {
// $haveModelCategory = true;
// }
// $haveMatrix = false;
// foreach ($product->getProductMenuMakers() as $productMenuMaker) {
// if ($productMenuMaker->getMatrixActives()->count() > 0) {
// $haveMatrix = true;
// }
// }
//
// if (!$haveModelCategory or !$haveMatrix) {
// return false;
// }
// if (!$haveModelCategory) {
// return false;
// }
if ($this->getProductPriceMockups()->count() == 0) {
return false;
}
}
return true;
}
public function getUrlName(): ?string
{
return $this->urlName;
}
public function setUrlName(string $urlName): self
{
$this->urlName = $urlName;
return $this;
}
public function getBuilderAccess(): ?bool
{
return $this->builderAccess;
}
public function setBuilderAccess(bool $builderAccess): self
{
$this->builderAccess = $builderAccess;
return $this;
}
/**
* @return Collection<int, ProductPicture>
*/
public function getProductPictures(): Collection
{
return $this->productPictures;
}
public function addProductPicture(ProductPicture $productPicture): self
{
if (!$this->productPictures->contains($productPicture)) {
$this->productPictures[] = $productPicture;
$productPicture->setProduct($this);
}
return $this;
}
public function removeProductPicture(ProductPicture $productPicture): self
{
if ($this->productPictures->removeElement($productPicture)) {
// set the owning side to null (unless already changed)
if ($productPicture->getProduct() === $this) {
$productPicture->setProduct(null);
}
}
return $this;
}
/**
* @return Collection<int, ProductReview>
*/
public function getProductReviews(): Collection
{
return $this->productReviews;
}
public function addProductReview(ProductReview $productReview): self
{
if (!$this->productReviews->contains($productReview)) {
$this->productReviews[] = $productReview;
$productReview->setProduct($this);
}
return $this;
}
public function removeProductReview(ProductReview $productReview): self
{
if ($this->productReviews->removeElement($productReview)) {
// set the owning side to null (unless already changed)
if ($productReview->getProduct() === $this) {
$productReview->setProduct(null);
}
}
return $this;
}
}