vendor/bluue/products-bundle/src/Entity/Product.php line 52

Open in your IDE?
  1. <?php
  2. /**
  3.  * @author Leo BANNHOLTZER (contact@scaledev.fr)
  4.  * @copyright 2021 - ScaleDEV SAS, 12 RUE CHARLES MORET, 10120 ST ANDRE LES VERGERS
  5.  * @license commercial
  6.  */
  7. declare(strict_types=1);
  8. namespace Bluue\ProductsBundle\Entity;
  9. use App\Entity\Context;
  10. use App\Entity\TaxRule;
  11. use App\Entity\Currency;
  12. use App\Entity\UnitMeasure;
  13. use Symfony\Component\Uid\Uuid;
  14. use Doctrine\ORM\Mapping as ORM;
  15. use Gedmo\Mapping\Annotation as Gedmo;
  16. use App\Entity\Traits\ContextServiceEntity;
  17. use Doctrine\Common\Collections\Collection;
  18. use Bluue\ProductsBundle\Entity\ProductType;
  19. use Bluue\ProductsBundle\Entity\ProductContext;
  20. use Bluue\ProductsBundle\Entity\RelatedProduct;
  21. use Bluue\ProductsBundle\Entity\PackProduct;
  22. use Doctrine\Common\Collections\ArrayCollection;
  23. use Bluue\ProductsBundle\Entity\ProductAttachment;
  24. use Bluue\ProductsBundle\Repository\ProductRepository;
  25. use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
  26. use Bluue\ProductsBundle\Validator\UniqueProductReferenceBrand;
  27. use App\DoctrineExtensions\Timestampable\Traits\UserTimestampableEntity;
  28. use App\DoctrineExtensions\SoftDeleteable\Traits\UserSoftDeleteableEntity;
  29. use App\Entity\User;
  30. use DateTime;
  31. use Bluue\ProductsBundle\Entity\ProductTag;
  32. /**
  33.  * @ORM\Entity(repositoryClass=ProductRepository::class)
  34.  * @ORM\Table(name="products_bundle__product", indexes={
  35.  *      @ORM\Index(name="reference_brand", columns={"reference_brand"}),
  36.  *      @ORM\Index(name="serial_number", columns={"serial_number"}),
  37.  *      @ORM\Index(name="deleted_at", columns={"deleted_at"}),
  38.  *      @ORM\Index(name="created_at", columns={"created_at"}),
  39.  *      @ORM\Index(name="updated_at", columns={"updated_at"}),
  40.  *      @ORM\Index(name="energy_code", columns={"energy_code"}),
  41.  *      @ORM\Index(name="available_for_supplier_purchase", columns={"available_for_supplier_purchase"}),
  42.  *  },
  43.  * )
  44.  * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=false)
  45.  * @UniqueProductReferenceBrand
  46.  */
  47. class Product
  48. {
  49.     use UserTimestampableEntity;
  50.     use UserSoftDeleteableEntity;
  51.     use ContextServiceEntity;
  52.     /**
  53.      * @ORM\Id
  54.      * @ORM\Column(type="uuid")
  55.      * @ORM\GeneratedValue(strategy="CUSTOM")
  56.      * @ORM\CustomIdGenerator(class=UuidGenerator::class)
  57.      */
  58.     private ?Uuid $id null;
  59.     /**
  60.      * @ORM\ManyToOne(targetEntity=ProductType::class, inversedBy="products", cascade={"persist"})
  61.      * @ORM\JoinColumn(nullable=false)
  62.      */
  63.     private ProductType $product_type;
  64.     /**
  65.      * @ORM\ManyToOne(targetEntity=UnitMeasure::class)
  66.      */
  67.     private ?UnitMeasure $unit_measure null;
  68.     /**
  69.      * @ORM\ManyToOne(targetEntity=Brand::class, inversedBy="products")
  70.      */
  71.     private ?Brand $brand null;
  72.     /**
  73.      * @ORM\ManyToOne(targetEntity=Product::class, inversedBy="childProducts")
  74.      */
  75.     private ?Product $parent null;
  76.     /**
  77.      * @ORM\OneToMany(targetEntity=Product::class, mappedBy="parent", cascade={"remove"}, fetch="EXTRA_LAZY")
  78.      */
  79.     private Collection $childProducts;
  80.     /**
  81.      * @ORM\Column(type="string", length=255, nullable=true)
  82.      */
  83.     private ?string $reference_brand null;
  84.     /**
  85.      * @ORM\Column(type="string", length=255, nullable=true)
  86.      */
  87.     private ?string $serialNumber null;
  88.     /**
  89.      * @ORM\OneToMany(
  90.      *     targetEntity=Ean13::class,
  91.      *     mappedBy="product",
  92.      *     cascade={"persist", "remove"},
  93.      *     fetch="EXTRA_LAZY")
  94.      */
  95.     private Collection $ean13s;
  96.     /**
  97.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable=true)
  98.      */
  99.     private ?string $initial_unit null;
  100.     /**
  101.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable=true)
  102.      */
  103.     private ?string $weight;
  104.     /**
  105.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable=true)
  106.      */
  107.     private ?string $width;
  108.     /**
  109.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable=true)
  110.      */
  111.     private ?string $height;
  112.     /**
  113.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable=true)
  114.      */
  115.     private ?string $depth;
  116.     /**
  117.      * @ORM\Column(type="string", length=10, nullable=true)
  118.      */
  119.     private ?string $customsCode null;
  120.     /**
  121.      * @ORM\Column(type="boolean", options={"default":"0"})
  122.      */
  123.     private bool $manufacturedPack false;
  124.     /**
  125.      * @ORM\Column(type="boolean", options={"default":"0"})
  126.      */
  127.     private bool $sellPriceFromChildren false;
  128.     /**
  129.      * @ORM\Column(type="boolean", options={"default":"0"})
  130.      */
  131.     private bool $retrieveInfoFromFirstChildOfPack false;
  132.     /**
  133.      * @ORM\Column(type="string", nullable=true)
  134.      */
  135.     private ?string $energyCode null;
  136.     /**
  137.      * @ORM\OneToMany(targetEntity=Declination::class, mappedBy="product", cascade={"remove"}, fetch="EXTRA_LAZY")
  138.      */
  139.     private Collection $declinations;
  140.     /**
  141.      * @ORM\OneToMany(targetEntity=ProductContext::class, mappedBy="product", cascade={"remove"}, fetch="EXTRA_LAZY")
  142.      */
  143.     private Collection $productContexts;
  144.     /**
  145.      * @ORM\OneToMany(targetEntity=RelatedProduct::class, mappedBy="parent", cascade={"remove"}, fetch="EXTRA_LAZY")
  146.      * @ORM\OrderBy({"position" = "ASC"})
  147.      */
  148.     private Collection $relatedProducts;
  149.     /**
  150.      * @ORM\OneToMany(targetEntity=PackProduct::class, mappedBy="parent", cascade={"remove"}, fetch="EXTRA_LAZY")
  151.      * @ORM\OrderBy({"position" = "ASC"})
  152.      */
  153.     private Collection $packProducts;
  154.     /**
  155.      * @ORM\OneToMany(
  156.      *  targetEntity=ProductAttachment::class,
  157.      *  mappedBy="product",
  158.      *  cascade={"persist", "remove"},
  159.      *  fetch="EXTRA_LAZY"
  160.      * )
  161.      */
  162.     private Collection $productAttachments;
  163.     /**
  164.      * @ORM\Column(type="boolean", options={"default":"0"})
  165.      */
  166.     private bool $noCustomerDiscount false;
  167.     /**
  168.      * @ORM\Column(type="boolean", options={"default":"1"})
  169.      */
  170.     private bool $availableForSupplierPurchase false;
  171.     /**
  172.      * @ORM\Column(type="json", nullable="true")
  173.      */
  174.     private array $options = [];
  175.     private ?Context $context null;
  176.     /**
  177.      * @ORM\OneToMany(
  178.      *  targetEntity="ProductTag",
  179.      *  mappedBy="product",
  180.      *  fetch="EXTRA_LAZY",
  181.      *  cascade={"persist", "remove"}
  182.      * )
  183.      */
  184.     private Collection $productTags;
  185.     /**
  186.      * @ORM\ManyToMany(targetEntity=User::class, fetch="EXTRA_LAZY")
  187.      * @ORM\JoinTable(
  188.      *     name="products_bundle__product_user",
  189.      *     joinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")},
  190.      *     inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
  191.      * )
  192.      */
  193.     private Collection $users;
  194.     // For stock bundle
  195.     private Collection $stockProducts;
  196.     private Collection $stockProductRoots;
  197.     public $stockProductConfiguration null;
  198.     public ?object $stockProductRoot null;
  199.     public $quantity_real null;
  200.     public $quantity_virtual null;
  201.     public $product_suppliers null;
  202.     public $giftCards null;
  203.     public $applyWholesalePriceToAllContexts null;
  204.     public $applySellPriceToAllContexts null;
  205.     public function __construct()
  206.     {
  207.         $this->childProducts = new ArrayCollection();
  208.         $this->declinations = new ArrayCollection();
  209.         $this->productContexts = new ArrayCollection();
  210.         $this->relatedProducts = new ArrayCollection();
  211.         $this->packProducts = new ArrayCollection();
  212.         $this->productAttachments = new ArrayCollection();
  213.         $this->productTags = new ArrayCollection();
  214.         $this->users = new ArrayCollection();
  215.         // For stock bundle.
  216.         $this->stockProducts = new ArrayCollection();
  217.         $this->stockProductRoots = new ArrayCollection();
  218.         $this->ean13s = new ArrayCollection();
  219.         $this->product_suppliers = new ArrayCollection();
  220.         $this->giftCards = new ArrayCollection();
  221.     }
  222.     /**
  223.      * @return Uuid|null
  224.      */
  225.     public function getId(): ?Uuid
  226.     {
  227.         return $this->id;
  228.     }
  229.     /**
  230.      * @return ProductType|null
  231.      */
  232.     public function getProductType(): ?ProductType
  233.     {
  234.         return $this->product_type;
  235.     }
  236.     /**
  237.      * @param ProductType|null $product_type
  238.      * @return $this
  239.      */
  240.     public function setProductType(?ProductType $product_type): self
  241.     {
  242.         $this->product_type $product_type;
  243.         return $this;
  244.     }
  245.     /**
  246.      * @return UnitMeasure|null
  247.      */
  248.     public function getUnitMeasure(): ?UnitMeasure
  249.     {
  250.         if ($this->unit_measure) {
  251.             return $this->unit_measure;
  252.         } elseif ($this->getParent() && $this->getParent()->getUnitMeasure()) {
  253.             return $this->getParent()->getUnitMeasure();
  254.         }
  255.         return null;
  256.     }
  257.     /**
  258.      * @param UnitMeasure|null $unit_measure
  259.      * @return $this
  260.      */
  261.     public function setUnitMeasure(?UnitMeasure $unit_measure): self
  262.     {
  263.         $this->unit_measure $unit_measure;
  264.         return $this;
  265.     }
  266.     /**
  267.      * @return Brand|null
  268.      */
  269.     public function getBrand(): ?Brand
  270.     {
  271.         return $this->brand;
  272.     }
  273.     /**
  274.      * @param Brand|null $brand
  275.      * @return $this
  276.      */
  277.     public function setBrand(?Brand $brand): self
  278.     {
  279.         $this->brand $brand;
  280.         return $this;
  281.     }
  282.     /**
  283.      * @return self|null
  284.      */
  285.     public function getParent(): ?self
  286.     {
  287.         return $this->parent;
  288.     }
  289.     /**
  290.      * @param self|null $parent
  291.      * @return $this
  292.      */
  293.     public function setParent(?self $parent): self
  294.     {
  295.         $this->parent $parent;
  296.         return $this;
  297.     }
  298.     /**
  299.      * @return Collection|self[]
  300.      */
  301.     public function getChildProducts(): Collection
  302.     {
  303.         return $this->childProducts;
  304.     }
  305.     /**
  306.      * @param self $childProduct
  307.      * @return $this
  308.      */
  309.     public function addChildProduct(self $childProduct): self
  310.     {
  311.         if (!$this->childProducts->contains($childProduct)) {
  312.             $this->childProducts[] = $childProduct;
  313.             $childProduct->setParent($this);
  314.         }
  315.         return $this;
  316.     }
  317.     /**
  318.      * @param self $childProduct
  319.      * @return $this
  320.      */
  321.     public function removeChildProduct(self $childProduct): self
  322.     {
  323.         if ($this->childProducts->removeElement($childProduct)) {
  324.             if ($childProduct->getParent() === $this) {
  325.                 $childProduct->setParent(null);
  326.             }
  327.         }
  328.         return $this;
  329.     }
  330.     /**
  331.      * @return string|null
  332.      */
  333.     public function getReferenceBrand(): ?string
  334.     {
  335.         return $this->reference_brand;
  336.     }
  337.     /**
  338.      * @param string|null $reference_brand
  339.      * @return $this
  340.      */
  341.     public function setReferenceBrand(?string $reference_brand): self
  342.     {
  343.         $this->reference_brand $reference_brand;
  344.         return $this;
  345.     }
  346.     /**
  347.      * @return string|null
  348.      */
  349.     public function getSerialNumber(): ?string
  350.     {
  351.         return $this->serialNumber;
  352.     }
  353.     /**
  354.      * @param string|null $serialNumber
  355.      * @return $this
  356.      */
  357.     public function setSerialNumber(?string $serialNumber): self
  358.     {
  359.         $this->serialNumber $serialNumber;
  360.         return $this;
  361.     }
  362.     /**
  363.      * @return Collection|Ean13[]
  364.      */
  365.     public function getEan13s(): Collection
  366.     {
  367.         return $this->ean13s;
  368.     }
  369.     /**
  370.      * @param Ean13 $ean13
  371.      * @return $this
  372.      */
  373.     public function addEan13(Ean13 $ean13): self
  374.     {
  375.         if (!$this->ean13s->contains($ean13)) {
  376.             $this->ean13s[] = $ean13;
  377.             $ean13->setProduct($this);
  378.         }
  379.         return $this;
  380.     }
  381.     /**
  382.      * @param Ean13 $ean13
  383.      * @return $this
  384.      */
  385.     public function removeEan13(Ean13 $ean13): self
  386.     {
  387.         $this->ean13s->removeElement($ean13);
  388.         return $this;
  389.     }
  390.     /**
  391.      * @return $this
  392.      */
  393.     public function removeAllEan13(): self
  394.     {
  395.         $this->ean13s->slice(0);
  396.         return $this;
  397.     }
  398.     public function getDefaultEan13()
  399.     {
  400.         $ean13 $this->ean13s->filter(function ($item) {
  401.             return $item->getIsDefault();
  402.         });
  403.         return count($ean13) ? $ean13->first() : false;
  404.     }
  405.     public function showDefaultEan13(): string
  406.     {
  407.         $default_ean13 $this->getDefaultEan13();
  408.         return $default_ean13 && !empty($default_ean13->getValue()) ? $default_ean13->getValue() : '';
  409.     }
  410.     /**
  411.      * @return string|null
  412.      */
  413.     public function getInitialUnit(): ?string
  414.     {
  415.         return $this->initial_unit;
  416.     }
  417.     /**
  418.      * @param string|null $initial_unit
  419.      * @return $this
  420.      */
  421.     public function setInitialUnit(?string $initial_unit): self
  422.     {
  423.         $this->initial_unit $initial_unit;
  424.         return $this;
  425.     }
  426.     /**
  427.      * @return string|null
  428.      */
  429.     public function getWeight(): ?string
  430.     {
  431.         return $this->weight;
  432.     }
  433.     /**
  434.      * @param string|null $weight
  435.      * @return $this
  436.      */
  437.     public function setWeight(?string $weight): self
  438.     {
  439.         $this->weight $weight;
  440.         return $this;
  441.     }
  442.     /**
  443.      * @return string|null
  444.      */
  445.     public function getWidth(): ?string
  446.     {
  447.         return $this->width;
  448.     }
  449.     /**
  450.      * @param string|null $width
  451.      * @return $this
  452.      */
  453.     public function setWidth(?string $width): self
  454.     {
  455.         $this->width $width;
  456.         return $this;
  457.     }
  458.     /**
  459.      * @return string|null
  460.      */
  461.     public function getHeight(): ?string
  462.     {
  463.         return $this->height;
  464.     }
  465.     /**
  466.      * @param string|null $height
  467.      * @return $this
  468.      */
  469.     public function setHeight(?string $height): self
  470.     {
  471.         $this->height $height;
  472.         return $this;
  473.     }
  474.     /**
  475.      * @return string|null
  476.      */
  477.     public function getDepth(): ?string
  478.     {
  479.         return $this->depth;
  480.     }
  481.     /**
  482.      * @param string|null $depth
  483.      * @return $this
  484.      */
  485.     public function setDepth(?string $depth): self
  486.     {
  487.         $this->depth $depth;
  488.         return $this;
  489.     }
  490.     /**
  491.      * https://www.tarifdouanier.eu/
  492.      * @return string|null
  493.      */
  494.     public function getCustomsCode(): ?string
  495.     {
  496.         return $this->customsCode;
  497.     }
  498.     /**
  499.      * @param string|null $customsCode
  500.      * @return $this
  501.      */
  502.     public function setCustomsCode(?string $customsCode): self
  503.     {
  504.         $this->customsCode $customsCode;
  505.         return $this;
  506.     }
  507.     /**
  508.      * @return bool
  509.      */
  510.     public function isManufacturedPack(): bool
  511.     {
  512.         return $this->manufacturedPack;
  513.     }
  514.     /**
  515.      * @param bool $manufacturedPack
  516.      * @return Product
  517.      */
  518.     public function setManufacturedPack(bool $manufacturedPack): Product
  519.     {
  520.         $this->manufacturedPack $manufacturedPack;
  521.         return $this;
  522.     }
  523.     /**
  524.      * @return bool
  525.      */
  526.     public function isSellPriceFromChildren(): bool
  527.     {
  528.         return $this->sellPriceFromChildren;
  529.     }
  530.     /**
  531.      * @param bool $sellPriceFromChildren
  532.      * @return Product
  533.      */
  534.     public function setSellPriceFromChildren(bool $sellPriceFromChildren): Product
  535.     {
  536.         $this->sellPriceFromChildren $sellPriceFromChildren;
  537.         return $this;
  538.     }
  539.     /**
  540.      * @return bool
  541.      */
  542.     public function getRetrieveInfoFromFirstChildOfPack(): bool
  543.     {
  544.         return $this->retrieveInfoFromFirstChildOfPack;
  545.     }
  546.     /**
  547.      * @param bool $retrieveInfoFromFirstChildOfPack
  548.      * @return Product
  549.      */
  550.     public function setRetrieveInfoFromFirstChildOfPack(bool $retrieveInfoFromFirstChildOfPack): Product
  551.     {
  552.         $this->retrieveInfoFromFirstChildOfPack $retrieveInfoFromFirstChildOfPack;
  553.         return $this;
  554.     }
  555.     /**
  556.      * @return string|null
  557.      */
  558.     public function getEnergyCode(): ?string
  559.     {
  560.         return $this->energyCode;
  561.     }
  562.     /**
  563.      * @param string|null $energyCode
  564.      * @return $this
  565.      */
  566.     public function setEnergyCode(?string $energyCode): self
  567.     {
  568.         $this->energyCode $energyCode;
  569.         return $this;
  570.     }
  571.     /**
  572.      * @return Collection|Declination[]
  573.      */
  574.     public function getDeclinations(?Context $context null): Collection
  575.     {
  576.         $declinations $this->declinations;
  577.         if ($context) {
  578.             $declinations $declinations->filter(function (Declination $declination) use ($context) {
  579.                 return $declination->getDeclinationContext($context) !== null;
  580.             });
  581.         }
  582.         $declinations $declinations->toArray();
  583.         usort($declinations, function ($a$b) {
  584.             return $a->getName() <=> $b->getName();
  585.         });
  586.         return new ArrayCollection($declinations);
  587.     }
  588.     /**
  589.      * @param Declination $declination
  590.      * @return $this
  591.      */
  592.     public function addDeclination(Declination $declination): self
  593.     {
  594.         if (!$this->declinations->contains($declination)) {
  595.             $this->declinations[] = $declination;
  596.             $declination->setProduct($this);
  597.         }
  598.         return $this;
  599.     }
  600.     /**
  601.      * @param Declination $declination
  602.      * @return $this
  603.      */
  604.     public function removeDeclination(Declination $declination): self
  605.     {
  606.         if ($this->declinations->removeElement($declination)) {
  607.             if ($declination->getProduct() === $this) {
  608.                 $declination->setProduct(null);
  609.             }
  610.         }
  611.         return $this;
  612.     }
  613.     /**
  614.      * @return Collection|ProductContext[]
  615.      */
  616.     public function getProductContexts(): Collection
  617.     {
  618.         return $this->productContexts;
  619.     }
  620.     /**
  621.      * @param ProductContext $productContext
  622.      * @return $this
  623.      */
  624.     public function addProductContext(ProductContext $productContext): self
  625.     {
  626.         if (!$this->productContexts->contains($productContext)) {
  627.             $this->productContexts[] = $productContext;
  628.             $productContext->setProduct($this);
  629.         }
  630.         return $this;
  631.     }
  632.     /**
  633.      * @param ProductContext $productContext
  634.      * @return $this
  635.      */
  636.     public function removeProductContext(ProductContext $productContext): self
  637.     {
  638.         if ($this->productContexts->removeElement($productContext)) {
  639.             if ($productContext->getProduct() === $this) {
  640.                 $productContext->setProduct(null);
  641.             }
  642.         }
  643.         return $this;
  644.     }
  645.     /**
  646.      * @param ?Context $context
  647.      * @return ProductContext|null
  648.      */
  649.     public function getProductContext(?Context $context null): ?ProductContext
  650.     {
  651.         $value null;
  652.         if ($this->getId()) {
  653.             if (!$this->context) {
  654.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  655.             } elseif ($context && $context != $this->context) {
  656.                 $this->context $context;
  657.             }
  658.             foreach ($this->getProductContexts() as $pc) {
  659.                 if ($pc->getContext() == $this->context) {
  660.                     $value $pc;
  661.                 }
  662.             }
  663.         }
  664.         return $value;
  665.     }
  666.     /**
  667.      * @param ?Context $context
  668.      * @return ProductImage|null
  669.      */
  670.     public function getCoverImageOfProductContext(?Context $context null): ?ProductImage
  671.     {
  672.         $productContext null;
  673.         if ($this->getId()) {
  674.             if (!$this->context) {
  675.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  676.             } elseif ($context && $context != $this->context) {
  677.                 $this->context $context;
  678.             }
  679.             foreach ($this->getProductContexts() as $pc) {
  680.                 if ($pc->getContext() == $this->context) {
  681.                     $productContext $pc;
  682.                 }
  683.             }
  684.         }
  685.         $image null;
  686.         if ($productContext) {
  687.             foreach ($productContext->getProductImages() as $pi) {
  688.                 if ($pi->getIsCover()) {
  689.                     $image $pi;
  690.                 }
  691.             }
  692.         }
  693.         return $image;
  694.     }
  695.     /**
  696.      * @return Collection|RelatedProduct[]
  697.      */
  698.     public function getRelatedProducts(): Collection
  699.     {
  700.         return $this->relatedProducts;
  701.     }
  702.     /**
  703.      * @param RelatedProduct $relatedProduct
  704.      * @return $this
  705.      */
  706.     public function addRelatedProduct(RelatedProduct $relatedProduct): self
  707.     {
  708.         if (!$this->relatedProducts->contains($relatedProduct)) {
  709.             $this->relatedProducts[] = $relatedProduct;
  710.             $relatedProduct->setParent($this);
  711.         }
  712.         return $this;
  713.     }
  714.     /**
  715.      * @return Collection|PackProduct[]
  716.      */
  717.     public function getPackProducts(): Collection
  718.     {
  719.         return $this->packProducts;
  720.     }
  721.     /**
  722.      * @param PackProduct $packProduct
  723.      * @return $this
  724.      */
  725.     public function addPackProduct(PackProduct $packProduct): self
  726.     {
  727.         if (!$this->packProducts->contains($packProduct)) {
  728.             $this->packProducts[] = $packProduct;
  729.             $packProduct->setParent($this);
  730.         }
  731.         return $this;
  732.     }
  733.     /**
  734.      * @return Collection|ProductAttachment[]
  735.      */
  736.     public function getProductAttachments(): Collection
  737.     {
  738.         return $this->productAttachments;
  739.     }
  740.     /**
  741.      * @param ProductAttachment $productAttachment
  742.      * @return $this
  743.      */
  744.     public function addProductAttachment(ProductAttachment $productAttachment): self
  745.     {
  746.         if (!$this->productAttachments->contains($productAttachment)) {
  747.             $this->productAttachments[] = $productAttachment;
  748.             $productAttachment->setProduct($this);
  749.         }
  750.         return $this;
  751.     }
  752.     /**
  753.      * @param bool|null $noCustomerDiscount
  754.      * @return $this
  755.      */
  756.     public function setNoCustomerDiscount(?bool $noCustomerDiscount): self
  757.     {
  758.         $this->noCustomerDiscount $noCustomerDiscount;
  759.         return $this;
  760.     }
  761.     /**
  762.      * @return bool|null
  763.      */
  764.     public function getNoCustomerDiscount(): ?bool
  765.     {
  766.         return $this->noCustomerDiscount;
  767.     }
  768.     /**
  769.      * @return bool
  770.      */
  771.     public function isAvailableForSupplierPurchase(): bool
  772.     {
  773.         return $this->availableForSupplierPurchase;
  774.     }
  775.     /**
  776.      * @param bool $availableForSupplierPurchase
  777.      * @return Product
  778.      */
  779.     public function setAvailableForSupplierPurchase(bool $availableForSupplierPurchase): Product
  780.     {
  781.         $this->availableForSupplierPurchase $availableForSupplierPurchase;
  782.         return $this;
  783.     }
  784.     /**
  785.      * @return array
  786.      */
  787.     public function getOptions(): array
  788.     {
  789.         return $this->options;
  790.     }
  791.     /**
  792.      * @param array $options
  793.      * @return $this
  794.      */
  795.     public function setOptions(array $options): self
  796.     {
  797.         $this->options $options;
  798.         return $this;
  799.     }
  800.     /**
  801.      * @param array $options
  802.      * @return $this
  803.      */
  804.     public function addOptions(array $options): self
  805.     {
  806.         return $this->setOptions(array_merge($this->options$options));
  807.     }
  808.     /**
  809.      * @return UnitMeasure|null
  810.      */
  811.     public function getRootUnitMeasure(): ?UnitMeasure
  812.     {
  813.         $rootUnitMeasure null;
  814.         if ($this->getChildProducts()->count()) {
  815.             foreach ($this->getChildProducts() as $childProduct) {
  816.                 if ($childProduct->getUnitMeasure()) {
  817.                     if ($childProduct->getUnitMeasure()->getParent()) {
  818.                         $rootUnitMeasure $childProduct->getUnitMeasure()->getParent();
  819.                     } else {
  820.                         $rootUnitMeasure $childProduct->getUnitMeasure();
  821.                     }
  822.                     break;
  823.                 }
  824.             }
  825.         } elseif ($this->getDeclinations()->count()) {
  826.             foreach ($this->getDeclinations() as $declination) {
  827.                 if ($declination->getUnitMeasure()) {
  828.                     if ($declination->getUnitMeasure()->getParent()) {
  829.                         $rootUnitMeasure $declination->getUnitMeasure()->getParent();
  830.                     } else {
  831.                         $rootUnitMeasure $declination->getUnitMeasure();
  832.                     }
  833.                     break;
  834.                 }
  835.             }
  836.         } elseif ($this->getParent() && $this->getParent()->getUnitMeasure()) {
  837.             if ($this->getParent()->getUnitMeasure()->getParent()) {
  838.                 $rootUnitMeasure $this->getParent()->getUnitMeasure()->getParent();
  839.             } else {
  840.                 $rootUnitMeasure $this->getParent()->getUnitMeasure();
  841.             }
  842.         }
  843.         return $rootUnitMeasure;
  844.     }
  845.     /**
  846.      * @param ?Context $context
  847.      * @return string|null
  848.      */
  849.     public function getName(?Context $context null): ?string
  850.     {
  851.         $value null;
  852.         if ($this->getId()) {
  853.             if (
  854.                 $this->getProductContexts()->count() == &&
  855.                 $this->getProductContexts()->first()->getContext() != $context
  856.             ) {
  857.                 $context $this->getProductContexts()->first()->getContext();
  858.             }
  859.             if (
  860.                 !$context
  861.                 && !$this->getProductContexts()->isEmpty()
  862.                 && !$this->getProductContext($this->context ?: $this->contextService->getActualOrDefault())
  863.             ) {
  864.                 $context $this->getProductContexts()->first()->getContext();
  865.             }
  866.             if (!$this->context) {
  867.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  868.             } elseif ($context && $context != $this->context) {
  869.                 $this->context $context;
  870.             }
  871.             foreach ($this->getProductContexts() as $pc) {
  872.                 if ($pc->getContext() == $this->context) {
  873.                     $value $pc->getName();
  874.                 }
  875.             }
  876.         }
  877.         return $value;
  878.     }
  879.     /**
  880.      * @param ?Context $context
  881.      * @return string|null
  882.      */
  883.     public function getMetaTagName(?Context $context null): ?string
  884.     {
  885.         $value null;
  886.         if ($this->getId()) {
  887.             if (!$this->context) {
  888.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  889.             } elseif ($context && $context != $this->context) {
  890.                 $this->context $context;
  891.             }
  892.             foreach ($this->getProductContexts() as $pc) {
  893.                 if ($pc->getContext() == $this->context) {
  894.                     $value $pc->getMetaTagName();
  895.                 }
  896.             }
  897.         }
  898.         return $value;
  899.     }
  900.     /**
  901.      * @param ?Context $context
  902.      * @return string|null
  903.      */
  904.     public function getDescription(?Context $context null): ?string
  905.     {
  906.         $value null;
  907.         if ($this->getId()) {
  908.             if (!$this->context) {
  909.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  910.             } elseif ($context && $context != $this->context) {
  911.                 $this->context $context;
  912.             }
  913.             foreach ($this->getProductContexts() as $pc) {
  914.                 if ($pc->getContext() == $this->context) {
  915.                     $value $pc->getDescription();
  916.                 }
  917.             }
  918.         }
  919.         return $value;
  920.     }
  921.     /**
  922.      * @param ?Context $context
  923.      * @return string|null
  924.      */
  925.     public function getMetaTagDescription(?Context $context null): ?string
  926.     {
  927.         $value null;
  928.         if ($this->getId()) {
  929.             if (!$this->context) {
  930.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  931.             } elseif ($context && $context != $this->context) {
  932.                 $this->context $context;
  933.             }
  934.             foreach ($this->getProductContexts() as $pc) {
  935.                 if ($pc->getContext() == $this->context) {
  936.                     $value $pc->getMetaTagDescription();
  937.                 }
  938.             }
  939.         }
  940.         return $value;
  941.     }
  942.     /**
  943.      * @param ?Context $context
  944.      * @return string|null
  945.      */
  946.     public function getSummary(?Context $context null): ?string
  947.     {
  948.         $value null;
  949.         if ($this->getId()) {
  950.             if (!$this->context) {
  951.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  952.             } elseif ($context && $context != $this->context) {
  953.                 $this->context $context;
  954.             }
  955.             foreach ($this->getProductContexts() as $pc) {
  956.                 if ($pc->getContext() == $this->context) {
  957.                     $value $pc->getSummary();
  958.                 }
  959.             }
  960.         }
  961.         return $value;
  962.     }
  963.     /**
  964.      * @param ?Context $context
  965.      * @return string|null
  966.      */
  967.     public function getSource(?Context $context null): ?string
  968.     {
  969.         $value null;
  970.         if ($this->getId()) {
  971.             if (!$this->context) {
  972.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  973.             } elseif ($context && $context != $this->context) {
  974.                 $this->context $context;
  975.             }
  976.             foreach ($this->getProductContexts() as $pc) {
  977.                 if ($pc->getContext() == $this->context) {
  978.                     $value $pc->getSource();
  979.                 }
  980.             }
  981.         }
  982.         return $value;
  983.     }
  984.     /**
  985.      * @param ?Context $context
  986.      * @return EcoPart|null
  987.      */
  988.     public function getEcoPart(?Context $context null): ?EcoPart
  989.     {
  990.         $value null;
  991.         if ($this->getId()) {
  992.             if (!$this->context) {
  993.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  994.             } elseif ($context && $context != $this->context) {
  995.                 $this->context $context;
  996.             }
  997.             foreach ($this->getProductContexts() as $pc) {
  998.                 if ($pc->getContext() == $this->context) {
  999.                     $value $pc->getEcoPart();
  1000.                 }
  1001.             }
  1002.         }
  1003.         return $value;
  1004.     }
  1005.     /**
  1006.      * @param ?Context $context
  1007.      * @return string|null
  1008.      */
  1009.     public function getEcoPartAmount(?Context $context null): ?string
  1010.     {
  1011.         $value null;
  1012.         if ($this->getId()) {
  1013.             if (!$this->context) {
  1014.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1015.             } elseif ($context && $context != $this->context) {
  1016.                 $this->context $context;
  1017.             }
  1018.             foreach ($this->getProductContexts() as $pc) {
  1019.                 if ($pc->getContext() == $this->context) {
  1020.                     $value $pc->getEcoPartAmount();
  1021.                 }
  1022.             }
  1023.         }
  1024.         return $value;
  1025.     }
  1026.     /**
  1027.      * @param ?Context $context
  1028.      * @return TaxRule|null
  1029.      */
  1030.     public function getTaxRule(?Context $context null): ?TaxRule
  1031.     {
  1032.         $value null;
  1033.         if ($this->getId()) {
  1034.             if (!$this->context) {
  1035.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1036.             } elseif ($context && $context != $this->context) {
  1037.                 $this->context $context;
  1038.             }
  1039.             foreach ($this->getProductContexts() as $pc) {
  1040.                 if ($pc->getContext() == $this->context) {
  1041.                     $value $pc->getTaxRule();
  1042.                 }
  1043.             }
  1044.         } elseif ($context) {
  1045.             foreach ($this->getProductContexts() as $pc) {
  1046.                 if ($pc->getContext() == $context) {
  1047.                     $value $pc->getTaxRule();
  1048.                 }
  1049.             }
  1050.         }
  1051.         return $value;
  1052.     }
  1053.     /**
  1054.      * @param ?Context $context
  1055.      * @return Currency|null
  1056.      */
  1057.     public function getCurrency(?Context $context null): ?Currency
  1058.     {
  1059.         $value null;
  1060.         if ($this->getId()) {
  1061.             if (
  1062.                 $this->getProductContexts()->count() == &&
  1063.                 $this->getProductContexts()->first()->getContext() != $context
  1064.             ) {
  1065.                 $context $this->getProductContexts()->first()->getContext();
  1066.             }
  1067.             if (
  1068.                 !$context
  1069.                 && !$this->getProductContexts()->isEmpty()
  1070.                 && !$this->getProductContext($this->context ?: $this->contextService->getActualOrDefault())
  1071.             ) {
  1072.                 $context $this->getProductContexts()->first()->getContext();
  1073.             }
  1074.             if (!$this->context) {
  1075.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1076.             } elseif ($context && $context != $this->context) {
  1077.                 $this->context $context;
  1078.             }
  1079.             foreach ($this->getProductContexts() as $pc) {
  1080.                 if ($pc->getContext() == $this->context) {
  1081.                     $value $pc->getCurrency();
  1082.                 }
  1083.             }
  1084.         }
  1085.         return $value;
  1086.     }
  1087.     /**
  1088.      * @param ?Context $context
  1089.      * @return string|null
  1090.      */
  1091.     public function getLinkRewrite(?Context $context null): ?string
  1092.     {
  1093.         $value null;
  1094.         if ($this->getId()) {
  1095.             if (!$this->context) {
  1096.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1097.             } elseif ($context && $context != $this->context) {
  1098.                 $this->context $context;
  1099.             }
  1100.             foreach ($this->getProductContexts() as $pc) {
  1101.                 if ($pc->getContext() == $this->context) {
  1102.                     $value $pc->getLinkRewrite();
  1103.                 }
  1104.             }
  1105.         }
  1106.         return $value;
  1107.     }
  1108.     /**
  1109.      * @param ?Context $context
  1110.      * @return bool|null
  1111.      */
  1112.     public function getIsActive(?Context $context null): ?bool
  1113.     {
  1114.         $value null;
  1115.         if ($this->getId()) {
  1116.             if (!$this->context) {
  1117.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1118.             } elseif ($context && $context != $this->context) {
  1119.                 $this->context $context;
  1120.             }
  1121.             foreach ($this->getProductContexts() as $pc) {
  1122.                 if ($pc->getContext() == $this->context) {
  1123.                     $value $pc->getIsActive();
  1124.                 }
  1125.             }
  1126.         }
  1127.         return $value;
  1128.     }
  1129.     /**
  1130.      * @param ?Context $context
  1131.      * @return bool|null
  1132.      */
  1133.     public function getAvailableForOrder(?Context $context null): ?bool
  1134.     {
  1135.         $value null;
  1136.         if ($this->getId()) {
  1137.             if (!$this->context) {
  1138.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1139.             } elseif ($context && $context != $this->context) {
  1140.                 $this->context $context;
  1141.             }
  1142.             foreach ($this->getProductContexts() as $pc) {
  1143.                 if ($pc->getContext() == $this->context) {
  1144.                     $value $pc->getAvailableForOrder();
  1145.                 }
  1146.             }
  1147.         }
  1148.         return $value;
  1149.     }
  1150.     /**
  1151.      * @param ?Context $context
  1152.      * @return int
  1153.      * 0 => refuser les commandes
  1154.      * 1 => accepter les commandes
  1155.      * 2 => comportement par défaut de presta
  1156.      */
  1157.     public function getOutOfStock(?Context $context null): int
  1158.     {
  1159.         $value null;
  1160.         if ($this->getId()) {
  1161.             if (!$this->context) {
  1162.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1163.             } elseif ($context && $context != $this->context) {
  1164.                 $this->context $context;
  1165.             }
  1166.             foreach ($this->getProductContexts() as $pc) {
  1167.                 if ($pc->getContext() == $this->context) {
  1168.                     $value $pc->getOutOfStock();
  1169.                 }
  1170.             }
  1171.         }
  1172.         return $value;
  1173.     }
  1174.     /**
  1175.      * @param ?Context $context
  1176.      * @return string|null
  1177.      */
  1178.     public function getReference(?Context $context null): ?string
  1179.     {
  1180.         $value null;
  1181.         if ($this->getId()) {
  1182.             if (
  1183.                 $this->getProductContexts()->count() == &&
  1184.                 $this->getProductContexts()->first()->getContext() != $context
  1185.             ) {
  1186.                 $context $this->getProductContexts()->first()->getContext();
  1187.             }
  1188.             if (
  1189.                 !$context
  1190.                 && !$this->getProductContexts()->isEmpty()
  1191.                 && !$this->getProductContext($this->context ?: $this->contextService->getActualOrDefault())
  1192.             ) {
  1193.                 $context $this->getProductContexts()->first()->getContext();
  1194.             }
  1195.             if (!$this->context) {
  1196.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1197.             } elseif ($context && $context != $this->context) {
  1198.                 $this->context $context;
  1199.             }
  1200.             foreach ($this->getProductContexts() as $pc) {
  1201.                 if ($pc->getContext() == $this->context) {
  1202.                     $value $pc->getReference();
  1203.                 }
  1204.             }
  1205.         }
  1206.         return $value;
  1207.     }
  1208.     /**
  1209.      * @param ?Context $context
  1210.      * @return string|null
  1211.      */
  1212.     public function getWholesalePrice(?Context $context null): ?string
  1213.     {
  1214.         $value null;
  1215.         if ($this->getId()) {
  1216.             if (!$this->context) {
  1217.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1218.             } elseif ($context && $context != $this->context) {
  1219.                 $this->context $context;
  1220.             }
  1221.             foreach ($this->getProductContexts() as $pc) {
  1222.                 if ($pc->getContext() == $this->context) {
  1223.                     $value $pc->getWholesalePrice();
  1224.                 }
  1225.             }
  1226.         }
  1227.         return $value;
  1228.     }
  1229.     /**
  1230.      * @param ?Context $context
  1231.      * @return DateTime|null
  1232.      */
  1233.     public function getCreatedAtWithContext(?Context $context null): ?DateTime
  1234.     {
  1235.         $value $this->getCreatedAt();
  1236.         if ($this->getId()) {
  1237.             if (!$this->context) {
  1238.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1239.             } elseif ($context && $context != $this->context) {
  1240.                 $this->context $context;
  1241.             }
  1242.             foreach ($this->getProductContexts() as $pc) {
  1243.                 if ($pc->getContext() == $this->context) {
  1244.                     $value $pc->getCreatedAt();
  1245.                 }
  1246.             }
  1247.         }
  1248.         return $value;
  1249.     }
  1250.     /**
  1251.      * @param ?Context $context
  1252.      * @return User|null
  1253.      */
  1254.     public function getCreatedByWithContext(?Context $context null): ?User
  1255.     {
  1256.         $value $this->getCreatedBy();
  1257.         if ($this->getId()) {
  1258.             if (!$this->context) {
  1259.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1260.             } elseif ($context && $context != $this->context) {
  1261.                 $this->context $context;
  1262.             }
  1263.             foreach ($this->getProductContexts() as $pc) {
  1264.                 if ($pc->getContext() == $this->context) {
  1265.                     $value $pc->getCreatedBy();
  1266.                 }
  1267.             }
  1268.         }
  1269.         return $value;
  1270.     }
  1271.     /**
  1272.      * @param ?Context $context
  1273.      * @return DateTime|null
  1274.      */
  1275.     public function getUpdatedAtWithContext(?Context $context null): ?DateTime
  1276.     {
  1277.         $value $this->getUpdatedAt();
  1278.         if ($this->getId()) {
  1279.             if (!$this->context) {
  1280.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1281.             } elseif ($context && $context != $this->context) {
  1282.                 $this->context $context;
  1283.             }
  1284.             foreach ($this->getProductContexts() as $pc) {
  1285.                 if ($pc->getContext() == $this->context) {
  1286.                     $value $pc->getUpdatedAt();
  1287.                 }
  1288.             }
  1289.         }
  1290.         return $value;
  1291.     }
  1292.     /**
  1293.      * @param ?Context $context
  1294.      * @return User|null
  1295.      */
  1296.     public function getUpdatedByWithContext(?Context $context null): ?User
  1297.     {
  1298.         $value $this->getUpdatedBy();
  1299.         if ($this->getId()) {
  1300.             if (!$this->context) {
  1301.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1302.             } elseif ($context && $context != $this->context) {
  1303.                 $this->context $context;
  1304.             }
  1305.             foreach ($this->getProductContexts() as $pc) {
  1306.                 if ($pc->getContext() == $this->context) {
  1307.                     $value $pc->getUpdatedBy();
  1308.                 }
  1309.             }
  1310.         }
  1311.         return $value;
  1312.     }
  1313.     /**
  1314.      * @param ?Context $context
  1315.      * @return string|null
  1316.      */
  1317.     public function getSellPrice(?Context $context null): ?string
  1318.     {
  1319.         $value null;
  1320.         if ($this->getId()) {
  1321.             if (!$this->context) {
  1322.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1323.             } elseif ($context && $context != $this->context) {
  1324.                 $this->context $context;
  1325.             }
  1326.             foreach ($this->getProductContexts() as $pc) {
  1327.                 if ($pc->getContext() == $this->context) {
  1328.                     $value $pc->getSellPrice();
  1329.                 }
  1330.             }
  1331.         }
  1332.         return $value;
  1333.     }
  1334.     /**
  1335.      * @param ?Context $context
  1336.      * @return bool|null
  1337.      */
  1338.     public function isChangeableTaxRule(?Context $context null): ?bool
  1339.     {
  1340.         $value null;
  1341.         if ($this->getId()) {
  1342.             if (!$this->context) {
  1343.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1344.             } elseif ($context && $context != $this->context) {
  1345.                 $this->context $context;
  1346.             }
  1347.             foreach ($this->getProductContexts() as $pc) {
  1348.                 if ($pc->getContext() == $this->context) {
  1349.                     $value $pc->isChangeableTaxRule();
  1350.                 }
  1351.             }
  1352.         }
  1353.         return $value;
  1354.     }
  1355.     /**
  1356.      * @param ?Context $context
  1357.      */
  1358.     public function getTranslations(?Context $context null)
  1359.     {
  1360.         $collection = [];
  1361.         if ($this->getId()) {
  1362.             if (
  1363.                 $this->getProductContexts()->count() == &&
  1364.                 $this->getProductContexts()->first()->getContext() != $context
  1365.             ) {
  1366.                 $context $this->getProductContexts()->first()->getContext();
  1367.             }
  1368.             if (
  1369.                 !$context
  1370.                 && !$this->getProductContexts()->isEmpty()
  1371.                 && !$this->getProductContext($this->context ?: $this->contextService->getActualOrDefault())
  1372.             ) {
  1373.                 $context $this->getProductContexts()->first()->getContext();
  1374.             }
  1375.             if (!$this->context) {
  1376.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1377.             } elseif ($context && $context != $this->context) {
  1378.                 $this->context $context;
  1379.             }
  1380.             foreach ($this->getProductContexts() as $pc) {
  1381.                 if ($pc->getContext() == $this->context) {
  1382.                     $collection $pc->getTranslations();
  1383.                 }
  1384.             }
  1385.         }
  1386.         return $collection;
  1387.     }
  1388.     /**
  1389.      * @param Context|null $context
  1390.      * @return string
  1391.      */
  1392.     public function getChoiceLabel(?Context $context null): string
  1393.     {
  1394.         if (
  1395.             $this->getProductContexts()->count() == &&
  1396.             $this->getProductContexts()->first()->getContext() != $context
  1397.         ) {
  1398.             $context $this->getProductContexts()->first()->getContext();
  1399.         }
  1400.         if (
  1401.             !$context
  1402.             && !$this->getProductContexts()->isEmpty()
  1403.             && !$this->getProductContext($this->context ?: $this->contextService->getActualOrDefault())
  1404.         ) {
  1405.             $context $this->getProductContexts()->first()->getContext();
  1406.         }
  1407.         $return '';
  1408.         if ($ref $this->getReference($context)) {
  1409.             $return '[' $ref '] ';
  1410.         }
  1411.         return $return $this->getName($context);
  1412.     }
  1413.     /**
  1414.      * @return bool
  1415.      */
  1416.     public function getIsPack(): bool
  1417.     {
  1418.         return $this->getId() && $this->getProductType()->getNumber() == 3;
  1419.     }
  1420.     // For stock bundle
  1421.     /**
  1422.      * @param Uuid|null $warehouseId
  1423.      * @param Context|null $context
  1424.      * @return Collection
  1425.      */
  1426.     public function getStockProducts(?Uuid $warehouseId null, ?Context $context null): Collection
  1427.     {
  1428.         $stockProducts $this->stockProducts->filter(function ($stockProduct) use ($context) {
  1429.             if ($context) {
  1430.                 return !$stockProduct->getDeclination() &&
  1431.                     $stockProduct->getStockProductRootContexts()->filter(
  1432.                         function ($stockProductRootContext) use ($context) {
  1433.                             return $stockProductRootContext->getContext() == $context;
  1434.                         }
  1435.                     )->count() > 0;
  1436.             }
  1437.             return !$stockProduct->getDeclination();
  1438.         });
  1439.         if ($warehouseId) {
  1440.             $stockProducts $stockProducts->filter(function ($stockProduct) use ($warehouseId) {
  1441.                 return $stockProduct->getWarehouse()->getId() == $warehouseId;
  1442.             });
  1443.         }
  1444.         return $stockProducts;
  1445.     }
  1446.     /**
  1447.      * @return Collection
  1448.      */
  1449.     public function getStockProductRoots(): Collection
  1450.     {
  1451.         return $this->stockProductRoots;
  1452.     }
  1453.     /**
  1454.      * @return object|null
  1455.      */
  1456.     public function getStockProductRoot(): ?object
  1457.     {
  1458.         $stockProductRoots $this->stockProductRoots->filter(function ($item) {
  1459.             return !$item->getDeclination();
  1460.         });
  1461.         return count($stockProductRoots) ? $stockProductRoots->first() : null;
  1462.     }
  1463.     /**
  1464.      * @param $stockProductRoot
  1465.      * @return $this
  1466.      */
  1467.     public function addStockProductRoot($stockProductRoot): self
  1468.     {
  1469.         if (!$this->stockProductRoots->contains($stockProductRoot)) {
  1470.             $this->stockProductRoots[] = $stockProductRoot;
  1471.             $stockProductRoot->setProduct($this);
  1472.         }
  1473.         return $this;
  1474.     }
  1475.     /**
  1476.      * @param $stockProductRoot
  1477.      * @return $this
  1478.      */
  1479.     public function removeStockProductRoot($stockProductRoot): self
  1480.     {
  1481.         if ($this->stockProductRoots->removeElement($stockProductRoot)) {
  1482.             if ($stockProductRoot->getProduct() === $this) {
  1483.                 $stockProductRoot->setProduct(null);
  1484.             }
  1485.         }
  1486.         return $this;
  1487.     }
  1488.     /**
  1489.      * @param Uuid|null $warehouseId
  1490.      * @return int
  1491.      */
  1492.     public function getStockProductsFinalQuantity(?Uuid $warehouseId null): int
  1493.     {
  1494.         $quantity 0;
  1495.         if ($warehouseId) {
  1496.             foreach ($this->getStockProducts($warehouseId) as $stock_product) {
  1497.                 $quantity += $stock_product->getQuantityAvailable();
  1498.             }
  1499.         } else {
  1500.             $quantity += $this->getStockProductRoot() ? $this->getStockProductRoot()->getQuantityAvailable() : 0;
  1501.         }
  1502.         return $quantity;
  1503.     }
  1504.     /**
  1505.      * @param $stockProducts
  1506.      * @return Product
  1507.      */
  1508.     public function setStockProducts($stockProducts): self
  1509.     {
  1510.         $this->stockProducts $stockProducts;
  1511.         return $this;
  1512.     }
  1513.     /**
  1514.      * @return Product
  1515.      */
  1516.     public function setStockProductRoot($stockProductRoot): self
  1517.     {
  1518.         $this->stockProductRoot $stockProductRoot;
  1519.         return $this;
  1520.     }
  1521.     /**
  1522.      * @param Context|null $context
  1523.      * @return object|null
  1524.      */
  1525.     public function getStockProductRootContext(?Context $context null): ?object
  1526.     {
  1527.         if (!$this->context) {
  1528.             $this->context $context ?: $this->contextService->getActualOrDefault();
  1529.         } elseif ($context && $context != $this->context) {
  1530.             $this->context $context;
  1531.         }
  1532.         return $this->getStockProductRoot() ?
  1533.             $this->getStockProductRoot()->getStockProductRootContext($this->context) : null
  1534.         ;
  1535.     }
  1536.     /**
  1537.      * @return Collection
  1538.      */
  1539.     public function getProductSuppliers(): Collection
  1540.     {
  1541.         return $this->product_suppliers;
  1542.     }
  1543.     public function getDefaultProductSupplier()
  1544.     {
  1545.         if ($this->product_suppliers) {
  1546.             if (!$this->context) {
  1547.                 $this->context $this->contextService->getActualOrDefault();
  1548.             }
  1549.             foreach ($this->product_suppliers as $product_supplier) {
  1550.                 foreach ($product_supplier->getProductSupplierContexts() as $psContext) {
  1551.                     if ($psContext->getContext()->getId() == $this->context->getId() && $psContext->getIsDefault()) {
  1552.                         return $product_supplier;
  1553.                     }
  1554.                 }
  1555.             }
  1556.         }
  1557.         return false;
  1558.     }
  1559.     /**
  1560.      * @return Collection|ProductTag[]
  1561.      */
  1562.     public function getProductTags(): Collection
  1563.     {
  1564.         return $this->productTags;
  1565.     }
  1566.     /**
  1567.      * @param ProductTag $productTag
  1568.      * @return $this
  1569.      */
  1570.     public function addProductTag(?ProductTag $productTag): self
  1571.     {
  1572.         if (!$this->productTags->contains($productTag)) {
  1573.             $this->productTags[] = $productTag;
  1574.             $productTag->setProduct($this);
  1575.         }
  1576.         return $this;
  1577.     }
  1578.     /**
  1579.      * @param ProductTag $productTag
  1580.      * @return $this
  1581.      */
  1582.     public function removeProductTag(ProductTag $productTag): self
  1583.     {
  1584.         $this->productTags->removeElement($productTag);
  1585.         return $this;
  1586.     }
  1587.     public function getUsers(): Collection
  1588.     {
  1589.         return $this->users;
  1590.     }
  1591.     public function getGiftCards()
  1592.     {
  1593.         return $this->giftCards;
  1594.     }
  1595.     public function getIsGiftCard()
  1596.     {
  1597.         return $this->getId() && $this->getProductType()->getNumber() == 10 true false;
  1598.     }
  1599.     /**
  1600.      * @param Context $context
  1601.      * @return int|null
  1602.      */
  1603.     public function getQuantityMin(?Context $context null)
  1604.     {
  1605.         $value null;
  1606.         if ($this->getId()) {
  1607.             if (!$this->context) {
  1608.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1609.             } elseif ($context && $context != $this->context) {
  1610.                 $this->context $context;
  1611.             }
  1612.             foreach ($this->getProductContexts() as $pc) {
  1613.                 if ($pc->getContext() == $this->context) {
  1614.                     $value $pc->getQuantityMin();
  1615.                 }
  1616.             }
  1617.         }
  1618.         return $value;
  1619.     }
  1620.     /**
  1621.      * @param Context|null $context
  1622.      * @return string|null
  1623.      */
  1624.     public function getVisibility(?Context $context null): ?string
  1625.     {
  1626.         $value null;
  1627.         if ($this->getId()) {
  1628.             if (!$this->context) {
  1629.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1630.             } elseif ($context && $context != $this->context) {
  1631.                 $this->context $context;
  1632.             }
  1633.             foreach ($this->getProductContexts() as $pc) {
  1634.                 if ($pc->getContext() == $this->context) {
  1635.                     $value $pc->getVisibility();
  1636.                 }
  1637.             }
  1638.         }
  1639.         return $value;
  1640.     }
  1641.     /**
  1642.      * @param Context|null $context
  1643.      * @return string|null
  1644.      */
  1645.     public function getRedirectType(?Context $context null): ?string
  1646.     {
  1647.         $value null;
  1648.         if ($this->getId()) {
  1649.             if (!$this->context) {
  1650.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1651.             } elseif ($context && $context != $this->context) {
  1652.                 $this->context $context;
  1653.             }
  1654.             foreach ($this->getProductContexts() as $pc) {
  1655.                 if ($pc->getContext() == $this->context) {
  1656.                     $value $pc->getRedirectType();
  1657.                 }
  1658.             }
  1659.         }
  1660.         return $value;
  1661.     }
  1662.     /**
  1663.      * @param Context|null $context
  1664.      * @return Product|null
  1665.      */
  1666.     public function getProductRedirect(?Context $context null): ?Product
  1667.     {
  1668.         $value null;
  1669.         if ($this->getId()) {
  1670.             if (!$this->context) {
  1671.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1672.             } elseif ($context && $context != $this->context) {
  1673.                 $this->context $context;
  1674.             }
  1675.             foreach ($this->getProductContexts() as $pc) {
  1676.                 if ($pc->getContext() == $this->context) {
  1677.                     $value $pc->getProductRedirect();
  1678.                 }
  1679.             }
  1680.         }
  1681.         return $value;
  1682.     }
  1683.     /**
  1684.      * @param Context|null $context
  1685.      * @return object|null
  1686.      */
  1687.     public function getCategoryRedirect(?Context $context null): ?object
  1688.     {
  1689.         $value null;
  1690.         if ($this->getId()) {
  1691.             if (!$this->context) {
  1692.                 $this->context $context ?: $this->contextService->getActualOrDefault();
  1693.             } elseif ($context && $context != $this->context) {
  1694.                 $this->context $context;
  1695.             }
  1696.             foreach ($this->getProductContexts() as $pc) {
  1697.                 if ($pc->getContext() == $this->context) {
  1698.                     $value $pc->getCategoryRedirect();
  1699.                 }
  1700.             }
  1701.         }
  1702.         return $value;
  1703.     }
  1704.     /**
  1705.      * @return Collection
  1706.      */
  1707.     public function getAllCategoryProducts(): Collection
  1708.     {
  1709.         $categoryProducts = [];
  1710.         foreach ($this->getProductContexts() as $pc) {
  1711.             $categoryProducts array_merge($categoryProducts$pc->getCategoryProducts()->toArray());
  1712.         }
  1713.         return new ArrayCollection($categoryProducts);
  1714.     }
  1715. }