<?php
declare (strict_types = 1);
namespace App\Entity\Core;
use App\Entity\ProductAttribute;
use App\Entity\ProductFile;
use App\Entity\Tag;
use App\Entity\RelatedProduct;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Core\Model\Product as BaseProduct;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductTaxon;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Product\Model\ProductTranslationInterface as BaseProductTranslationInterface;
/**
* @ORM\MappedSuperclass
* @ORM\Table(name="sylius_product")
*/
class Product extends BaseProduct implements ProductInterface
{
public const SIMPLE = 1;
public const BY_METRE = 2;
public const BY_BATCH = 3;
public const CUSTOM = 4;
public const SESSION_IDS = 'productIds';
public const DEFAULT_TAX_CATEGORY_CODE = 'iva';
public const DEFAULT_SHIPPING_CATEGORY_CODE = 'shippable';
public const DEFAULT_CHANNEL_CODE = 'ES_CL_WEB';
public const DEFAULT_VARIANT_SELECTION = 'choice';
/**
* @var bool
*
* @ORM\Column(name="can_be_estimated", type="boolean", nullable=false)
*/
private $canBeEstimated = false;
/**
* @var bool
*
* @ORM\Column(name="can_be_sold", type="boolean", nullable=false)
*/
private $canBeSold = false;
/**
* @var string
*
* @ORM\Column(name="company", type="string", nullable=false)
*/
private $company;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Tag")
*/
private $tags;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="App\Entity\ProductFile", mappedBy="product", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $productFiles;
/**
* @var int
*
* @ORM\Column(name="type", type="integer", nullable=false)
*/
private $type;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="App\Entity\ProductAttribute", mappedBy="product", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $productAttributes;
/**
* @var bool
*
* @ORM\Column(name="admin_enabled", type="boolean", nullable=false)
*/
private $adminEnabled = true;
/**
* @var bool
*
* @ORM\Column(name="stock_needed", type="boolean", nullable=false)
*/
private $stockNeeded = true;
/**
* @var bool
*
* @ORM\Column(name="by_metre", type="boolean", nullable=false)
*/
private $byMetre = false;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="App\Entity\RelatedProduct", mappedBy="section", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $relatedProducts;
public function __construct()
{
parent::__construct();
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
$this->productFiles = new \Doctrine\Common\Collections\ArrayCollection();
$this->productAttributes = new \Doctrine\Common\Collections\ArrayCollection();
$this->relatedProducts = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getCanBeEstimated(): bool
{
return $this->canBeEstimated;
}
public function setCanBeEstimated(bool $canBeEstimated): void
{
$this->canBeEstimated = $canBeEstimated;
}
public function getCanBeSold(): bool
{
return $this->canBeSold;
}
public function setCanBeSold(bool $canBeSold): void
{
$this->canBeSold = $canBeSold;
}
public function getCompany(): ?string
{
return $this->company;
}
public function setCompany(string $company): void
{
$this->company = $company;
}
public function addTag(Tag $tag)
{
$this->tags[] = $tag;
return $this;
}
public function removeTag(Tag $tag)
{
return $this->tags->removeElement($tag);
}
public function getTags()
{
return $this->tags;
}
/**
* @return Collection|ProductFile[]
*/
public function getProductFiles() : Collection
{
return $this->productFiles;
}
public function addProductFile(ProductFile $productFile): self
{
if (!$this->productFiles->contains($productFile)) {
$this->productFiles[] = $productFile;
$productFile->setProduct($this);
}
return $this;
}
public function removeProductFile(ProductFile $productFile): self
{
if ($this->productFiles->contains($productFile)) {
$this->productFiles->removeElement($productFile);
// set the owning side to null (unless already changed)
if ($productFile->getProduct() === $this) {
$productFile->setProduct(null);
}
}
return $this;
}
public function setType(int $type): self
{
$this->type = $type;
return $this;
}
public function getType(): ?int
{
return $this->type;
}
public static function getTypesList(bool $flip = false): array
{
$list = [
self::SIMPLE => 'simple',
self::BY_METRE => 'by_metre',
self::BY_BATCH => 'by_batch',
self::CUSTOM => 'custom'
];
return $flip ? array_flip($list) : $list;
}
public static function getTypeName(int $type): ?string
{
$types = self::getTypesList();
$typeName = $types[$type] ?? null;
return $typeName;
}
public function getCurrentTypeValue(): ?string
{
return self::getTypeName($this->type);
}
public function usesMetres(): bool
{
switch ($this->getType()) {
case self::SIMPLE:
$usesMetres = false;
break;
case self::BY_METRE:
$usesMetres = true;
break;
case self::BY_BATCH:
if ($this->getByMetre()) {
$usesMetres = true;
} else {
$usesMetres = false;
}
break;
case self::CUSTOM:
if ($this->getByMetre()) {
$usesMetres = true;
} else {
$usesMetres = false;
}
break;
default:
$usesMetres = false;
break;
}
return $usesMetres;
}
public function addProductAttribute(ProductAttribute $productAttribute)
{
$productAttribute->setProduct($this);
$this->productAttributes[] = $productAttribute;
return $this;
}
public function removeProductAttribute(ProductAttribute $productAttribute)
{
return $this->productAttributes->removeElement($productAttribute);
}
public function getProductAttributes()
{
return $this->productAttributes;
}
public function getAdminEnabled(): bool
{
return $this->adminEnabled;
}
public function setAdminEnabled(bool $adminEnabled): void
{
$this->adminEnabled = $adminEnabled;
}
public function getChildrenLeafOfTaxon(TaxonInterface $taxon): ?TaxonInterface
{
$result = $taxon;
foreach ($this->getTaxons() as $productTaxon) {
if (!$productTaxon->hasChildren()) {
$ancestors = $productTaxon->getAncestors();
if ($ancestors->contains($taxon)) {
$result = $productTaxon;
break;
}
}
}
return $result;
}
public function clearProductTaxons(): void
{
foreach ($this->getProductTaxons() as $productTaxon) {
$this->removeProductTaxon($productTaxon);
}
}
public function addProductTaxonFromTaxon(TaxonInterface $taxon): void
{
$newProductTaxon = new ProductTaxon;
$newProductTaxon->setTaxon($taxon);
$newProductTaxon->setProduct($this);
$this->addProductTaxon($newProductTaxon);
}
public function setProductTaxonsFromTaxons(array $taxons): void
{
$firstTaxon = count($taxons) > 0 ? $taxons[0] : null;
$this->clearProductTaxons();
foreach ($taxons as $taxon) {
$this->addProductTaxonFromTaxon($taxon);
}
if ($firstTaxon) {
$this->setMainTaxon($firstTaxon);
}
}
public function getStockNeeded(): bool
{
return $this->stockNeeded;
}
public function setStockNeeded(bool $stockNeeded): void
{
$this->stockNeeded = $stockNeeded;
}
public function getByMetre(): bool
{
return $this->byMetre;
}
public function setByMetre(bool $byMetre): void
{
$this->byMetre = $byMetre;
}
protected function createTranslation(): BaseProductTranslationInterface
{
return new ProductTranslation();
}
public function __toString(): string
{
return $this->code . ' - ' . $this->getName();
}
public function addRelatedProduct(RelatedProduct $relatedProduct)
{
$relatedProduct->setProduct($this);
$this->relatedProducts[] = $relatedProduct;
return $this;
}
public function removeRelatedProduct(RelatedProduct $relatedProduct)
{
return $this->relatedProducts->removeElement($relatedProduct);
}
public function getRelatedProducts()
{
return $this->relatedProducts;
}
}