<?php
namespace App\AtechNet\CoreBundle\Entity;
use App\AtechNet\CoreBundle\Helper\Collections;
use App\AtechNet\CoreBundle\Translation\TranslationHelper;
use App\AtechNet\CoreBundle\Translation\TranslatorInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\JoinTable;
use Doctrine\ORM\Mapping\ManyToMany;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\ORM\Mapping\OrderBy;
use Doctrine\ORM\Mapping\Table as Table;
use Doctrine\ORM\Mapping\UniqueConstraint;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Entity(repositoryClass="App\AtechNet\CoreBundle\Repository\ProductRepository")
* @Table(name="products", uniqueConstraints={
* @UniqueConstraint(name="unique_product_code", columns={"type_id", "code"}),
* })
*
* @UniqueEntity(
* fields={"type", "code"},
* errorPath="code",
* message="This Id is already in use with that type. Try to save it again."
* )
* @UniqueEntity(
* fields={"ean"},
* errorPath="ean",
* message="This EAN is already in use.",
* ignoreNull=true
* )
* @UniqueEntity(
* fields={"partNumber"},
* errorPath="partNumber",
* message="This Part Number is already in use.",
* ignoreNull=true
* )
*
* @HasLifecycleCallbacks
*/
class Product extends AbstractSignedEntity
{
public const string Unit_Pcs = 'pcs';
public const int SHIPPING_ID = 82;
public const int CASH_ON_DELIVERY_PRODUCT_ID = 23848;
public const int COMPENSATION_ITEM_ID = 31175;
public const int CABLE_POWER_PRODUCT_ID = 2285;
public const int CABLE_POWER_UK_PRODUCT_ID = 12638;
public const int CABLE_POWER_UK_MALE_PRODUCT_ID = 12637;
public const int CABLE_POWER_UK_FEMALE_PRODUCT_ID = 26954;
public const int CABLE_POWER_CH_NOTEBOOK_PRODUCT_ID = 64928;
public const int CABLE_POWER_CH_COMPUTER_PRODUCT_ID = 68732;
public const int PRODUCT_IN_STOCK_AVAILABLE_STOCK_MOVEMENT_QTY_REFRESH_LIMIT = 2000;
public const int ADATTORLO_PRODUCT_ID = 30896;
public const int ESET_NOD32_90_DAY_TRIAL_PRODUCT_ID = 35249;
public const int GDATA_90_DAY_TRIAL_PRODUCT_ID = 37334;
public const int MPL_PACKAGE_FEE_PRODUCT_ID = 41630;
public const int KEYBOARD_STICKER_SK_CZ_ID = 191;
public const int KEYBOARD_STICKER_HU_ID = 2656;
public const int UNIDENTIFIED_PRODUCT_ID = 55679;
public const int SUMMER_2026_COUPON_GIFT_ITEM_ID = 67485;
public const int PEXESO_SCHOOL_GIFT_ITEM_ID = 70223;
public const int BATTERY_USED_70 = 70831;
public const int BATTERY_USED_71 = 70832;
/**
* @return array
*/
public static function getUnitChoices(): array
{
return [
self::Unit_Pcs => self::Unit_Pcs,
];
}
public const OutOfStockStatus_Empty = 0;
public const OutOfStockStatus_NotVisibleDefault = 1;
public const OutOfStockStatus_VisibleComingSoon = 2;
public const OutOfStockStatus_VisibleSoldOut = 3;
public const OutOfStockStatus_VisibleShadow = 4;
public const OutOfStockStatus_VisibleOrderable5Days = 5;
public const OutOfStockStatus_VisibleOrderable10Days = 6;
public const OutOfStockStatus_VisibleOrderable15Days = 7;
/**
* @return array
*/
public static function getStockStatusChoices(): array
{
return [
self::OutOfStockStatus_Empty => 'Empty',
self::OutOfStockStatus_NotVisibleDefault => 'Not visible, default',
self::OutOfStockStatus_VisibleComingSoon => 'Visible, coming soon (cannot order)',
self::OutOfStockStatus_VisibleSoldOut => 'Visible, sold out listed (cannot order)',
self::OutOfStockStatus_VisibleShadow => 'Visible, shadow',
self::OutOfStockStatus_VisibleOrderable5Days => 'Visible, orderable, 5 days',
self::OutOfStockStatus_VisibleOrderable10Days => 'Visible, orderable, 10 days',
self::OutOfStockStatus_VisibleOrderable15Days => 'Visible, orderable, 15 days',
];
}
/**
* @return array
*/
public static function getVisibleOutOfStockStatusChoices(): array
{
$stockStatusChoices = self::getStockStatusChoices();
unset($stockStatusChoices[self::OutOfStockStatus_Empty]);
unset($stockStatusChoices[self::OutOfStockStatus_NotVisibleDefault]);
return $stockStatusChoices;
}
public const QualityStatus_Empty = 0;
public const QualityStatus_Platinum = 1;
public const QualityStatus_Unpacked = 2;
public const QualityStatus_Refurbished_A_Plus = 3;
public const QualityStatus_Gold = 4;
public const QualityStatus_Silver = 5;
public const QualityStatus_Bronze = 6;
public const QualityStatus_Iron = 7;
public const QualityStatus_New = 8;
public const QualityStatus_Bazaar = 9;
/**
* @return array
*/
public static function getQualityStatusChoices(): array
{
return [
self::QualityStatus_Empty => 'Empty',
self::QualityStatus_New => 'New',
self::QualityStatus_Platinum => 'Platinum',
self::QualityStatus_Gold => 'Gold',
self::QualityStatus_Silver => 'Silver',
self::QualityStatus_Bronze => 'Bronze',
self::QualityStatus_Bazaar => 'Bazaar',
];
}
/**
* @return array
*/
public static function getQualityStatusKeys(): array
{
return [
self::QualityStatus_Empty,
self::QualityStatus_New,
self::QualityStatus_Platinum,
self::QualityStatus_Gold,
self::QualityStatus_Silver,
self::QualityStatus_Bronze,
self::QualityStatus_Bazaar,
];
}
/**
* @return array
*/
public static function getQualityStatusAsAttributeOptionId(): array
{
return [
self::QualityStatus_Bazaar => AttributeOption::ATTRIBUTE_OPTION_QUALITY_BAZAAR,
self::QualityStatus_Bronze => AttributeOption::ATTRIBUTE_OPTION_QUALITY_BRONZ,
self::QualityStatus_Silver => AttributeOption::ATTRIBUTE_OPTION_QUALITY_SILVER,
self::QualityStatus_Gold => AttributeOption::ATTRIBUTE_OPTION_QUALITY_GOLD,
self::QualityStatus_New => AttributeOption::ATTRIBUTE_OPTION_QUALITY_NEW,
self::QualityStatus_Platinum => AttributeOption::ATTRIBUTE_OPTION_QUALITY_PLATINUM,
];
}
/**
* @return array
*/
public static function getEUQualityStatusPairs(): array
{
return [
self::QualityStatus_Empty => 'Empty',
self::QualityStatus_New => 'New',
self::QualityStatus_Platinum => 'A',
self::QualityStatus_Gold => 'A',
self::QualityStatus_Silver => 'A',
self::QualityStatus_Bronze => 'B+',
self::QualityStatus_Bazaar => 'C',
];
}
/**
* @param $key
* @return mixed|null
*/
public static function getQualityStatusTitleForKey($key)
{
return self::getQualityStatusChoices()[$key] ?? null;
}
public const string PRODUCT_BADGE_GAMER = 'gamer';
public const string PRODUCT_BADGE_WORKSTATION = 'workstation';
public const string PRODUCT_BADGE_2_IN_1 = '2in1 notebook';
public const string PRODUCT_BADGE_CHROMEBOOK = 'Chromebook';
public const string PRODUCT_BADGE_TINY_PC = 'Tiny PC';
public const string PRODUCT_BADGE_BESTSELLER = 'bestseller';
/**
* @return array
*/
public static function getBadgesChoices(): array
{
return [
'gamer' => 'gamer',
'work' => 'work',
'travel' => 'travel',
'senior' => 'senior',
'internet' => 'internet',
'win10' => 'win10',
'workstation' => 'workstation',
'Tiny PC' => 'Tiny PC',
'2in1 notebook' => '2in1 notebook',
'Chromebook' => 'Chromebook',
'Notebook bundle' => 'Notebook bundle',
'Skin' => 'Skin',
'Skinable' => 'Skinable',
'Ultrabook' => 'Ultrabook',
'Windows 11' => 'Windows 11',
'Touchscreen' => 'Touchscreen',
'bestseller' => 'bestseller'
];
}
public const giftCartIds = [
48709,
48708,
48707,
48706,
];
public const int MARGIN_LEVEL_NO = 0;
public const int MARGIN_LEVEL_A = 1;
public const int MARGIN_LEVEL_B = 2;
public const int MARGIN_LEVEL_C = 3;
public const int MARGIN_LEVEL_D = 4;
public const int MARGIN_LEVEL_E = 5;
public const int MARGIN_LEVEL_F = 6;
/**
* @return string[]
*/
public static function getMarginLevelChoices(): array
{
return [
self::MARGIN_LEVEL_NO => 'NO',
self::MARGIN_LEVEL_A => 'A',
self::MARGIN_LEVEL_B => 'B',
self::MARGIN_LEVEL_C => 'C',
self::MARGIN_LEVEL_D => 'D',
self::MARGIN_LEVEL_E => 'E',
self::MARGIN_LEVEL_F => 'F'
];
}
/**
* @var string
*
* @Column(name="omega_plu", type="text", nullable=true)
*/
private $omegaPlu = null;
/**
* Unified Unique ID
*
* @var string
*
* @Column(name="code", type="string", nullable=false)
*/
private $code;
/**
* @var Vendor
*
* @ManyToOne(targetEntity="Vendor")
* @JoinColumn(name="vendor_id", referencedColumnName="id")
*/
private $vendor;
/**
* @var ProductType
*
* @Assert\NotNull
*
* @ManyToOne(targetEntity="ProductType")
* @JoinColumn(name="type_id", referencedColumnName="id")
*/
private $type;
/**
* @var Album
*
* @Assert\NotNull
*
* @OneToOne(targetEntity="Album", cascade={"persist", "remove"})
* @JoinColumn(name="photo_album_id", referencedColumnName="id")
*/
private $album;
/**
* @var string
*
* @Assert\NotNull
*
* @Column(name="name", type="text")
*/
private $name;
/**
* @var Collection<int, ProductModel>
* @ManyToMany(targetEntity="ProductModel", mappedBy="connectedProducts")
* @OrderBy({"created" = "DESC"})
*/
private $connectedProductModels;
/**
* @var Collection<int, Product>
*
* @ManyToMany(targetEntity="Product", inversedBy="parentAlternativeProducts")
* @JoinTable(
* name="products_alternative_products",
* joinColumns={
* @JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @JoinColumn(name="alternative_product_id", referencedColumnName="id")
* })
* @OrderBy({"id" = "DESC"})
*/
private $alternativeProducts;
/**
* @var Collection<int, Product>
*
* @ManyToMany(targetEntity="Product", mappedBy="alternativeProducts")
* @OrderBy({"id" = "DESC"})
*/
private $parentAlternativeProducts;
/**
* @var Product|null
*
* @ManyToOne(targetEntity="Product")
* @JoinColumn(name="current_alternative_product_id", referencedColumnName="id", nullable=true)
*/
private ?Product $currentAlternativeProduct = null;
/**
* @var int
*
* @Assert\NotNull
*
* @Column(name="warranty", type="integer")
*/
private $warranty;
/**
* @var string
*
* @Column(name="part_number", type="text", nullable=true)
*/
private $partNumber = null;
/**
* @var string
*
* @Column(name="ean", type="text", nullable=true)
*/
private $ean = null;
/**
* @var string
*
* @Column(name="gtin", type="text", nullable=true)
*/
private $gtin = null;
/**
* @var string
*
* @Column(name="amazon_code", type="text", nullable=true)
*/
private $amazonCode = null;
/**
* @var int
*
* @Column(name="length", type="integer")
*/
private $length = 0;
/**
* @var string
*
* @Column(name="width", type="integer")
*/
private $width = 0;
/**
* @var string
*
* @Column(name="height", type="integer")
*/
private $height = 0;
/**
* @var string
*
* @Column(name="weight", type="integer")
*/
private $weight = 0;
/**
* @var string
*
* @Assert\NotNull
*
* @Column(name="unit", type="string")
*/
private $unit;
/**
* @var array
*
* @Assert\NotNull
*
* @Column(name="badges", type="array")
*/
private $badges = [];
/**
* @var string
*
* @Column(name="detail", type="text", nullable=true)
*/
private $detail = null;
/**
* @var string
*
* @Column(name="stock_position", type="text", length=96, nullable=true)
*/
private $stockPosition;
/**
* @var int
*
* @Column(name="out_of_stock_status", type="integer")
*/
private $outOfStockStatus = 1;
/**
* @var Collection
*
* @OneToMany(targetEntity="ProductMeta", mappedBy="product", cascade={"persist", "remove"})
**/
private $metas;
/**
* @var Collection
*
* @Assert\Valid
*
* @OneToMany(targetEntity="ProductAttribute", mappedBy="product", cascade={"persist", "remove"})
**/
private $productAttributes;
/**
* @var Collection
*
* @Assert\Valid
*
* @OneToMany(targetEntity="ProductContainer", mappedBy="product", cascade={"persist", "remove"})
**/
private $productContainers;
/**
* @var Collection
*
* @Assert\Valid
*
* @OneToMany(targetEntity="ProductContainer", mappedBy="child", cascade={"persist", "remove"})
**/
private $childContainers;
/**
* @var Collection
*
* @Assert\Valid
*
* @OneToMany(targetEntity="ProductCommission", mappedBy="product", cascade={"persist", "remove"})
**/
private $commissions;
/**
* @var Collection
*
* @Assert\Valid
*
* @OneToMany(targetEntity="OrderItem", mappedBy="product", cascade={"persist", "remove"})
**/
private $orderItems;
/**
* @var Collection
*
* @Assert\Valid
**/
private $reservations;
/**
* @var int
*
* @Assert\NotNull
*
* @Column(name="quality_status", type="integer")
*/
private $qualityStatus;
/**
* @var \DateTime
*
* @Column(name="sold_out_date", type="datetime", nullable=true, options={"comment":"Generated value on update if cache_available became 0."})
*/
private $soldOutDate;
/**
* @var string
*
* @Column(name="cache_description", type="text", nullable=true, options={"comment":"Generated value on insert and update."})
*/
private $cacheDescription;
/**
* @var \DateTime
*
* @Column(name="cache_item_last_updated", type="datetime", nullable=false, options={"comment":"Generated value on insert and update."})
*/
private $cacheItemLastUpdated;
/**
* @var int
*
* @Column(name="available", type="integer", nullable=false)
*/
private $available = 0;
/**
* @var int
*
* @Column(name="in_stock", type="integer", nullable=false)
*/
private $inStock = 0;
/**
* @var bool
*
* @Column(name="archived", type="boolean")
*/
private $archived;
/**
* @var bool
*
* @Column(name="scannable", type="boolean")
*/
private $scannable = true;
/**
* @var float
*
* @Column(name="last_price", type="float", nullable=false)
*/
private $lastPrice = 0;
/**
* @var float
*
* @Column(name="avg_price", type="float", nullable=false)
*/
private $avgPrice = 0;
/**
* @var Collection
*
* @OneToMany(targetEntity="StockMovementItem", mappedBy="product", orphanRemoval=true, fetch="EXTRA_LAZY")
* @OrderBy({"created" = "DESC"})
**/
private $stockMovementItems;
/**
* @var bool
*
* @Column(name="container", type="boolean")
*/
private $container = false;
/**
* @var Collection
*
* @ManyToMany(targetEntity="CategoryPage", mappedBy="products")
* @OrderBy({"id" = "DESC"})
*/
private $categoryPages;
/**
* @var Collection
*
* @ManyToMany(targetEntity="CategoryPage", mappedBy="popularProducts")
* @OrderBy({"id" = "DESC"})
*/
private $popularProductsCategoryPages;
/**
* @var Collection
*
* @ManyToMany(targetEntity="ProductTag", mappedBy="products")
* @OrderBy({"id" = "DESC"})
*/
private $tags;
/**
* @var Collection
*
* @OneToMany(targetEntity="CustomerNotification", mappedBy="product")
*/
private $notifications;
/**
* @var Collection
*
* @OneToMany(targetEntity="ProductPriceLog", mappedBy="product")
**/
private $priceLogEntries;
/**
* @var \DateTime
*
* @Column(name="last_sale", type="datetime", nullable=true)
*/
private $lastSale = null;
/**
* @var Collection
*
* @OneToMany(targetEntity="ProductExternalFeedName", mappedBy="product", cascade={"persist", "remove"})
*/
private $externalFeedNames;
/**
* @var int
*
* @Column(name="cpu_mark", type="integer")
*/
private $cpuMark = 0;
/**
* @var ProductModel
*
* @ManyToOne(targetEntity="ProductModel", inversedBy="products")
* @JoinColumn(name="product_model_id", referencedColumnName="id", nullable=true)
*/
private $productModel;
/**
* @var bool
*
* @Column(name="spare_part_card", type="boolean")
*/
private $sparePartCard = false;
/**
* @var float
*
* @Column(name="spare_part_price", type="float", nullable=false)
*/
private $sparePartPrice = 0;
/**
* @var int
*
* @Column(name="sold_during_time_frame", type="integer", nullable=false, options={"default": 0}) */
private $soldDuringTimeFrame = 0;
/**
* @var \DateTime
*
* @Column(name="spare_part_created", type="datetime", nullable=true)
*/
private $sparePartCreated = null;
/**
* @var \DateTime
*
* @Column(name="spare_part_updated", type="datetime", nullable=true)
*/
private $sparePartUpdated = null;
/**
* @var User
*
* @ManyToOne(targetEntity="User")
* @JoinColumn(name="spare_part_created_by", referencedColumnName="id", nullable=true)
*/
private $sparePartCreatedBy = null;
/**
* @var User
*
* @ManyToOne(targetEntity="User")
* @JoinColumn(name="spare_part_updated_by", referencedColumnName="id", nullable=true)
*/
private $sparePartUpdatedBy = null;
/**
* @var int
*
* @Column(name="margin_level", type="integer", nullable=false)
*/
private $marginLevel = 0;
/**
* @var Collection
*
* @ManyToMany(targetEntity="Coupon", mappedBy="products")
*/
private $coupons;
/**
* @var int|null
*
* @Column(name="quantity_limit", type="integer", nullable=true)
*/
private $quantityLimit;
/**
* @var bool
*
* @Column(name="availability_paused_for_product_model", type="boolean")
*/
private $availabilityPausedForProductModel = false;
/**
* @var Collection
*
* @OneToMany(targetEntity="ProductVariation", mappedBy="product", orphanRemoval=true)
* @OrderBy({"created" = "DESC"})
**/
private $productVariations;
/**
* @var FixedAttributeOptionCombination
*
* @ManyToOne(targetEntity="FixedAttributeOptionCombination", inversedBy="products")
* @JoinColumn(name="fixed_attribute_option_combination_id", referencedColumnName="id", nullable=true)
*/
private $fixedAttributeOptionCombination;
/**
* @var int
*
* @Column(name="last_qty_calculated_for_marketplaces", type="integer", nullable=false)
*/
private $lastQtyCalculatedForMarketplaces = 0;
/**
* @var int
*
* @Column(name="calculated_qty_grade_new", type="integer", nullable=false)
*/
private $calculatedQtyGradeNew = 0;
/**
* @var int
*
* @Column(name="calculated_qty_grade_a", type="integer", nullable=false)
*/
private $calculatedQtyGradeA = 0;
/**
* @var int
*
* @Column(name="calculated_qty_grade_b", type="integer", nullable=false)
*/
private $calculatedQtyGradeB = 0;
/**
* @var int
*
* @Column(name="calculated_qty_grade_c", type="integer", nullable=false)
*/
private $calculatedQtyGradeC = 0;
/**
* @var int
*
* @Column(name="calculated_qty_grade_d", type="integer", nullable=false)
*/
private $calculatedQtyGradeD = 0;
/**
* @var \DateTime
*
* @Column(name="calculated_qty_date", type="datetime", nullable=true)
*/
private $lastQtySyncDate;
/**
* @var Collection
*
* @OneToMany(targetEntity="CustomerClaimProduct", mappedBy="product")
*/
private $customerClaimProducts;
public function __construct()
{
parent::__construct();
$this->customerClaimProducts = new ArrayCollection();
$this->cacheItemLastUpdated = new \DateTime();
$this->productAttributes = new ArrayCollection();
$this->metas = new ArrayCollection();
$this->stockMovementItems = new ArrayCollection();
$this->productContainers = new ArrayCollection();
$this->childContainers = new ArrayCollection();
$this->tags = new ArrayCollection();
$this->priceLogEntries = new ArrayCollection();
$this->externalFeedNames = new ArrayCollection();
$this->coupons = new ArrayCollection();
$this->productVariations = new ArrayCollection();
$this->connectedProductModels = new ArrayCollection();
$this->alternativeProducts = new ArrayCollection();
$this->parentAlternativeProducts = new ArrayCollection();
}
/**
* @return ProductType
*/
public function getType()
{
return $this->type ?? $this->productModel?->getType() ?? null;
}
/**
* @param ProductType $productType
*/
public function setType($productType)
{
$this->type = $productType;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return Collection
*/
public function getProductAttributes()
{
return $this->productAttributes;
}
/**
* Add ProductAttribute
*
* @param ProductAttribute $prodAttribute
* @return ProductAttribute
*/
public function addProductAttribute($prodAttribute)
{
if (!$this->productAttributes->contains($prodAttribute)) {
$this->productAttributes->add($prodAttribute);
$prodAttribute->setProduct($this);
}
return $this;
}
/**
* Remove ProductAttribute
*
* @param ProductAttribute $prodAttribute
* @return ProductAttribute
*/
public function removeProductAttribute($prodAttribute)
{
$this->productAttributes->removeElement($prodAttribute);
return $this;
}
/**
* @param string $code
*/
public function setCode($code)
{
$this->code = $code;
}
/**
* @return string
*/
public function getCode()
{
return $this->code;
}
/**
* Get current price for given domain
*
* @param Domain $domain
* @return float
*/
public function getCurrentPriceForDomain($domain)
{
$metaForDomain = $this->getDomainMeta($domain);
if (!$metaForDomain) {
return 0;
}
if ($metaForDomain->isDiscounted()) {
return $metaForDomain->getDomainDiscount();
}
return $metaForDomain->getDomainPrice();
}
/**
* Get current vat price for given domain
*
* @param Domain $domain
* @return float
*/
public function getCurrentVatPriceForDomain($domain, $useDiscount = true)
{
$metaForDomain = $this->getDomainMeta($domain);
if (!$metaForDomain) {
return 0;
}
if ($metaForDomain->isDiscounted() && $useDiscount) {
return $metaForDomain->getDomainVatDiscount();
}
return $metaForDomain->getDomainVatPrice();
}
/**
* @param Domain $domain
* @param Customer $customer
* @param bool $showCurrency
* @return float
*/
public function getCurrentRealPrice($domain, $customer, $showCurrency = false)
{
$metaForDomain = $this->getDomainMeta($domain);
if ($metaForDomain->isDiscounted()) {
if ($customer->getVatId() == '' || $customer->getVatId() == null) {
$price = $metaForDomain->getDomainVatDiscount();
} else {
$price = $metaForDomain->getDomainDiscount();
}
} else {
if ($customer->getVatId() == '' || $customer->getVatId() == null) {
$price = $metaForDomain->getDomainVatPrice();
} else {
$price = $metaForDomain->getDomainPrice();
}
}
if ($showCurrency) {
$price = $price . ' ' . $domain->getCurrency();
}
return $price;
}
/**
* @return Album
*/
public function getAlbum()
{
return $this->album;
}
/**
* @param Album $album
*/
public function setAlbum($album)
{
$this->album = $album;
}
/**
* @return Collection
*/
public function getMetas()
{
$orderedMetas = [];
$metas = $this->metas;
foreach ($metas as $meta) {
$orderedMetas[$meta->getDomain()->getSortIndex() - 1] = $meta;
}
ksort($orderedMetas);
return $orderedMetas;
}
/**
* @param Domain $domain
* @return ProductMeta|bool
*/
public function getDomainMeta($domain)
{
/**
* @var ProductMeta $meta
*/
foreach ($this->getMetas() as $meta) {
if ($meta->getDomain()->getId() === $domain->getId()) {
return $meta;
}
}
return false;
}
/**
* @param int $domainId
* @return ProductMeta|bool
*/
public function getDomainMetaByDomainId($domainId)
{
/**
* @var ProductMeta $meta
*/
foreach ($this->getMetas() as $meta) {
if ($meta->getDomain()->getId() === $domainId) {
return $meta;
}
}
return false;
}
/**
* Add ProductMeta
*
* @param ProductMeta $meta
* @return Product
*/
public function addMeta($meta)
{
if (!$this->metas->contains($meta)) {
$this->metas->add($meta);
$meta->setProduct($this);
}
return $this;
}
/**
* Remove ProductMeta
*
* @param ProductMeta $meta
* @return Product
*/
public function removeMeta($meta)
{
$this->metas->removeElement($meta);
return $this;
}
/**
* @return string
*/
public function getEan()
{
return $this->ean;
}
/**
* @param string $prefix
* @return string
*/
public function getFormattedEan($prefix = 'FRB')
{
$validEanLength = 13;
$lengthWithPrefixAndCode = strlen($prefix . $this->code);
$zeroesLength = $validEanLength - $lengthWithPrefixAndCode;
$formattedEan = $prefix;
for ($i = 0; $i < $zeroesLength; $i++) {
$formattedEan .= '0';
}
$formattedEan .= $this->code;
return $formattedEan;
}
/**
* @param string $ean
*/
public function setEan($ean)
{
$this->ean = $ean;
}
/**
* @return string
*/
public function getPartNumber()
{
return $this->partNumber;
}
/**
* @param string $partNumber
*/
public function setPartNumber($partNumber)
{
$this->partNumber = $partNumber;
}
/**
* @return integer
*/
public function getLength()
{
return $this->length;
}
/**
* @param integer $length
*/
public function setLength($length)
{
$this->length = $length;
}
/**
* @return integer
*/
public function getWidth()
{
return $this->width;
}
/**
* @param integer $width
*/
public function setWidth($width)
{
$this->width = $width;
}
/**
* @return integer
*/
public function getHeight()
{
return $this->height;
}
/**
* @param integer $height
*/
public function setHeight($height)
{
$this->height = $height;
}
/**
* @return integer
*/
public function getWeight()
{
return $this->weight;
}
/**
* @param integer $weight
*/
public function setWeight($weight)
{
$this->weight = $weight;
}
/**
* @return integer
*/
public function getSoldDuringTimeFrame()
{
return $this->soldDuringTimeFrame;
}
/**
* @param integer $SoldDuringTimeFrame
*/
public function setSoldDuringTimeFrame($soldDuringTimeFrame)
{
$this->soldDuringTimeFrame = $soldDuringTimeFrame;
}
/**
* @return string
*/
public function getUnit()
{
return $this->unit;
}
/**
* @param string $unit
*/
public function setUnit($unit)
{
if ($unit !== self::Unit_Pcs) {
throw new \LogicException('Invalid Product Unit.');
}
$this->unit = $unit;
}
/**
* @return boolean
**/
public function isAvailable()
{
if ($this->getAvailable() > 0 || $this->outOfStockStatus == self::OutOfStockStatus_VisibleShadow) {
return true;
}
return false;
}
/**
* @return bool
*/
public function isReservable(): bool
{
if (in_array($this->outOfStockStatus, [self::OutOfStockStatus_VisibleOrderable5Days, self::OutOfStockStatus_VisibleOrderable10Days, self::OutOfStockStatus_VisibleOrderable15Days])) {
return true;
}
return false;
}
/**
* @return int
**/
public function getAvailable()
{
return $this->available;
}
/**
* @param int $available
*/
public function setAvailable($available)
{
$this->available = $available;
}
/**
* @return int
**/
public function getLastQtyCalculatedForMarketplaces()
{
return $this->lastQtyCalculatedForMarketplaces;
}
/**
* @param int $lastQtyCalculatedForMarketplaces
*/
public function setLastQtyCalculatedForMarketplaces($lastQtyCalculatedForMarketplaces)
{
$this->lastQtyCalculatedForMarketplaces = $lastQtyCalculatedForMarketplaces;
}
/**
* @return \DateTime
*/
public function getItemLastUpdated()
{
return $this->cacheItemLastUpdated;
}
/**
* @return Vendor
*/
public function getVendor()
{
return $this->vendor ?? $this->productModel?->getVendor() ?? null;
}
/**
* @param Vendor $vendor
*/
public function setVendor($vendor)
{
$this->vendor = $vendor;
}
/**
* @param TranslatorInterface|null $translator
* @param bool $inverted
* @return string
*/
public function getFullTitle(TranslatorInterface $translator = null, $inverted = false)
{
$vendor = $this->vendor ? $this->vendor->getName() : $this->productModel->getVendor()->getName();
$type = $this->type ? $this->type->getTitle($translator) : $this->productModel->getType()->getTitle($translator);
if ($vendor !== 'VARIOUS' && $type !== 'OTHER' && $type !== 'Service') {
return sprintf('%s %s %s', $type, $vendor, $this->getName());
} else {
if ($vendor == 'VARIOUS' && ($type == 'OTHER' || $type == 'Service')) {
return $this->getName();
} elseif ($vendor !== 'VARIOUS' && ($type == 'OTHER' || $type == 'Service')) {
return sprintf('%s %s', $vendor, $this->getName());
} elseif ($vendor == 'VARIOUS' && $type !== 'OTHER' && $type !== 'Service') {
return $inverted ? sprintf('%s %s', $this->getName(), $type) : sprintf('%s %s', $type, $this->getName());
}
}
}
/**
* @param TranslatorInterface|null $translator
* @param bool $inverted
* @return string
*/
public function getFullTitleLatestTable(TranslatorInterface $translator = null, $inverted = false)
{
$vendor = $this->vendor ? $this->vendor->getName() : $this->productModel->getVendor()->getName();
$type = $this->type ? $this->type->getTitle($translator) : $this->productModel->getType()->getTitle($translator);
if ($vendor !== 'VARIOUS' && $type !== 'OTHER' && $type !== 'Service') {
return sprintf('%s %s %s', $type, $vendor, $this->getName());
} else {
if ($vendor == 'VARIOUS' && ($type == 'OTHER' || $type == 'Service')) {
return $this->getName();
} elseif ($vendor !== 'VARIOUS' && ($type == 'OTHER' || $type == 'Service')) {
return sprintf('%s %s', $vendor, $this->getName());
} elseif ($vendor == 'VARIOUS' && $type !== 'OTHER' && $type !== 'Service') {
return $inverted ? sprintf('%s', $this->getName()) : sprintf('%s', $this->getName());
}
}
}
public function getLongName($withStockStatus = true)
{
$values = [];
$values[] = $this->getCode();
$values[] = $this->getType()->getTitle();
if ('VARIOUS' != $this->getVendor()->getName()) {
$values[] = $this->getVendor()->getName();
}
$values[] = $this->getName();
$desc = $this->getDescription();
if ($desc != null) {
$values[] = $desc;
}
if ($withStockStatus) {
$values[] = '(' . $this->getAvailable() . '/' . $this->getInStock() . ')';
}
return implode(' - ', $values);
}
public function getLongName2() // Stock movements
{
$name = $this->getCode() . ' - ' . $this->getType()->getTitle();
if ('VARIOUS' != $this->getVendor()->getName()) {
$name .= ' ' . $this->getVendor()->getName();
}
$name .= ' ' . $this->getName();
$desc = $this->getDescription();
if ($desc != null) {
$name .= ' - ' . $desc;
}
return $name;
}
private $pageFileName = [];
/**
* The result is cached after the first call. The extension is not cached, it's always appended.
*
* @param TranslatorInterface $translator
* @param string $ext
* @param $fromCache
* @return string without php
* @internal param array $translationArray
*/
public function getPageFileName(TranslatorInterface $translator = null, $ext = '.php', $fromCache = true)
{
$transName = ($translator == null ? 'default' : $translator->getName());
if (!isset($this->pageFileName[$transName]) || !$fromCache) {
$type = preg_replace('/^\W+|\W+$/', '', TranslationHelper::ascii_convert($this->getType()->getTitle($translator)));
$type = preg_replace('/\W+/', '-', $type);
$name = preg_replace('/^\W+|\W+$/', '', TranslationHelper::ascii_convert($this->getName()));
$name = preg_replace('/\W+/', '-', $name);
$vendor = $this->getVendor()->getName();
if ($vendor != 'UNKNOWN') {
$vendor = preg_replace('/^\W+|\W+$/', '', $this->getVendor()->getName());
$vendor = preg_replace('/\W+/', '-', $vendor);
$fileName = sprintf("%s-%s-%s-%d", $type, $vendor, $name, $this->getId());
} else {
$fileName = sprintf("%s-%s-%d", $type, $name, $this->getId());
}
$fileName = strtolower($fileName);
if ($fromCache) {
$this->pageFileName[$transName] = $fileName;
} else {
return $fileName;
}
}
return $this->pageFileName[$transName] . $ext;
}
/**
* @param string $description
*/
public function setDescription($description)
{
$this->cacheDescription = $description;
}
/**
* @return string
*/
public function getDescription()
{
return $this->cacheDescription;
}
public function getNonCoaDescription($domainId)
{
if ($domainId == 1 || $domainId == 3) {
return str_replace([' | Win 7 Pro COA', ' | Win 7 Home COA'], ['', ''], $this->cacheDescription);
}
return $this->cacheDescription;
}
private $confProdAttr = null;
/**
* @param bool $fromCache
* @return array
*/
public function getConfigurationAttributes($fromCache = true)
{
if ($this->confProdAttr == null || !$fromCache) {
$confProdAttr = [];
/**
* @var ProductAttribute $prodAttr
*/
foreach ($this->productAttributes as $prodAttr) {
$attr = $prodAttr->getOption()->getAttribute();
if ($attr->isConfigurator()) {
$confProdAttr[] = $prodAttr;
}
}
uasort($confProdAttr, [$this, 'compareProductAttribute']);
if ($fromCache) {
$this->confProdAttr = $confProdAttr;
} else {
return $confProdAttr;
}
}
return $this->confProdAttr;
}
/**
* @param ProductAttribute $a
* @param ProductAttribute $b
* @return int
*/
public function compareProductAttribute(ProductAttribute $a, ProductAttribute $b)
{
return $this->compareVariousAttributeOptions($a->getOption(), $b->getOption());
}
/**
* @return bool
*/
public function hasConfigurationAttributes()
{
return count($this->getConfigurationAttributes()) > 0;
}
private $confAttrOptions = null;
/**
* The result is cached after the first call.
*
* @param bool $fromCache
* @return array
*/
public function getConfigurationAttributeOptions($fromCache = true)
{
if ($this->confAttrOptions == null || !$fromCache) {
$attrOptions = [];
/**
* @var ProductAttribute $prodAttr
*/
foreach ($this->getConfigurationAttributes() as $prodAttr) {
if (!$prodAttr->isUsed()) {
$option = $prodAttr->getOption();
$attrOptions[$option->getId()] = $option;
}
}
//uasort($attrOptions, array($this, 'compareVariousAttributeOptions'));
if ($fromCache) {
$this->confAttrOptions = $attrOptions;
} else {
return $attrOptions;
}
}
return $this->confAttrOptions;
}
/**
* @return bool
*/
public function hasConfigurationAttributeOptions()
{
return count($this->getConfigurationAttributeOptions()) > 0;
}
private $specAttrOptions = null;
/**
* The result is cached after the first call.
*
* @param bool $fromCache
* @return array
*/
public function getSpecificationAttributeOptions($fromCache = true)
{
if ($this->specAttrOptions == null || !$fromCache) {
$attrOptions = [];
/**
* @var ProductAttribute $prodAttr
*/
foreach ($this->productAttributes as $prodAttr) {
if ($prodAttr->getOption()->getAttribute()->getType() == 'conf') {
$option = $prodAttr->getOption();
$attrOptions[$option->getId()] = $option;
}
}
uasort($attrOptions, [$this, 'compareVariousAttributeOptions']);
if ($fromCache) {
$this->specAttrOptions = $attrOptions;
} else {
return $attrOptions;
}
}
return $this->specAttrOptions;
}
private $specProductAttrOptions = null;
/**
* The result is cached after the first call.
*
* @param bool $fromCache
* @return array
*/
public function getSpecificationProductAttributeOptions($fromCache = true)
{
if ($this->specProductAttrOptions == null || !$fromCache) {
$attrOptions = [];
/**
* @var ProductAttribute $prodAttr
*/
foreach ($this->productAttributes as $prodAttr) {
if ($prodAttr->getOption()->getAttribute()->getType() == 'conf') {
$option = $prodAttr;
$attrOptions[$option->getId()] = $option;
}
}
uasort($attrOptions, [$this, 'compareVariousProductAttributeOptions']);
if ($fromCache) {
$this->specProductAttrOptions = $attrOptions;
} else {
return $attrOptions;
}
}
return $this->specProductAttrOptions;
}
private $accAttrOptions = null;
/**
* The result is cached after the first call.
*
* @param bool $fromCache
* @param bool $withAlwaysIncludedAttributes
* @return array
*/
public function getAccessoryAttributeOptions($fromCache = true, $withAlwaysIncludedAttributes = false)
{
if ($this->accAttrOptions == null || !$fromCache) {
$attrOptions = [];
/**
* @var ProductAttribute $prodAttr
*/
foreach ($this->productAttributes as $prodAttr) {
if (!$withAlwaysIncludedAttributes && $prodAttr->isAlways()) {
continue;
}
$option = $prodAttr->getOption();
if ($option->getAttribute()->isAccessory()) {
$attrOptions[$option->getId()] = $option;
}
}
uasort($attrOptions, [$this, 'compareVariousAttributeOptions']);
if ($fromCache) {
$this->accAttrOptions = $attrOptions;
} else {
return $attrOptions;
}
}
return $this->accAttrOptions;
}
private $accProductAttrOptions = null;
/**
* The result is cached after the first call.
*
* @param bool $fromCache
* @return array
*/
public function getAccessoryProductAttributeOptions($fromCache = true)
{
if ($this->accProductAttrOptions == null || !$fromCache) {
$attrOptions = [];
/**
* @var ProductAttribute $prodAttr
*/
foreach ($this->productAttributes as $prodAttr) {
if ($prodAttr->getOption()->getAttribute()->isAccessory()) {
$attrOptions[$prodAttr->getId()] = $prodAttr;
}
}
uasort($attrOptions, [$this, 'compareVariousProductAttributeOptions']);
if ($fromCache) {
$this->accProductAttrOptions = $attrOptions;
} else {
return $attrOptions;
}
}
return $this->accProductAttrOptions;
}
/**
* @return bool
*/
public function hasAccessoryAttributeOptions()
{
return count($this->getAccessoryAttributeOptions()) > 0;
}
/**
* @param AttributeOption $a
* @param AttributeOption $b
* @return int
*/
public static function compareVariousAttributeOptions(AttributeOption $a, AttributeOption $b)
{
$result = Collections::compare($a->getAttribute(), $b->getAttribute());
if ($result == 0) {
return Collections::compareGraph($a, $b);
}
return $result;
}
/**
* @param ProductAttribute $a
* @param ProductAttribute $b
* @return int
*/
public static function compareVariousProductAttributeOptions(ProductAttribute $a, ProductAttribute $b)
{
$result = Collections::compare($a->getOption()->getAttribute(), $b->getOption()->getAttribute());
if ($result == 0) {
return Collections::compareGraph($a->getOption(), $b->getOption());
}
return $result;
}
/**
* @return int
*/
public function getWarranty()
{
return $this->warranty;
}
/**
* @param int $warranty
*/
public function setWarranty($warranty)
{
$this->warranty = $warranty;
}
/**
* @return array
*/
public function getBadges()
{
if (!$this->isAvailable()) {
return array_diff($this->badges, ['24h']);
}
return $this->badges;
}
/**
* @param string $badges
*/
public function setBadges($badges)
{
$this->badges = $badges;
}
/**
* @param string $badge
* @return void
*/
public function addToBadgeList(string $badge): void
{
$badges = $this->badges;
if (!$this->hasBadgeItem($badge)) {
$badges[] = $badge;
$this->setBadges($badges);
}
}
/**
* @param string $badge
* @return boolean
*/
public function hasBadgeItem(string $badge): bool
{
return in_array($badge, $this->getBadges());
}
public function removeBadgeItem(string $badge): void
{
$badges = $this->badges;
$arrayKeyToRemove = null;
foreach ($badges as $key => $value) {
if ($value == $badge) {
$arrayKeyToRemove = $key;
break;
}
}
if (!is_null($arrayKeyToRemove)) {
unset($badges[$arrayKeyToRemove]);
$this->setBadges($badges);
}
}
/**
* @return string
*/
public function getDetail()
{
return $this->detail;
}
/**
* @param string $detail
*/
public function setDetail($detail)
{
$this->detail = $detail;
}
public function getFormatDetail()
{
return self::createFormatedDetail($this->detail);
}
/**
* @return string|null
*/
public function getStockPosition(): ?string
{
return $this->stockPosition;
}
/**
* @param string|null $stockPosition
*/
public function setStockPosition(?string $stockPosition)
{
if (is_null($stockPosition)) {
$this->stockPosition = null;
} else {
$this->stockPosition = mb_substr($stockPosition, 0, 96);
}
}
/**
* @return string
*/
public function getOmegaPlu()
{
return $this->omegaPlu;
}
/**
* @param string $omegaPlu
*/
public function setOmegaPlu($omegaPlu)
{
$this->omegaPlu = $omegaPlu;
}
/**
* Initialize cache fields used at display. Cached values are stored in database.
* You have to call this method whenever the product or product depending object change.
*/
public function initCacheFields()
{
//sort description
$separator = ' | ';
$desc = '';
/**
* Clear cache
* @var AttributeOption $option
*/
foreach ($this->getSpecificationAttributeOptions(false) as $option) {
if ($option->isInShortDesc()) {
if ($desc !== '') {
$desc .= $separator;
}
/**
* if HDD, SSD, SSHD show attribute title after option title
*/
if (in_array($option->getAttribute()->getId(), [5, 6, 7, 8, 9, 166])) {
$desc .= $option->getTitle() . ' ' . $option->getAttribute()->getTitle();
} else {
$desc .= $option->getTitle();
}
}
}
$this->cacheDescription = $desc;
}
/**
* @return boolean
*/
public function isShadow()
{
if ($this->outOfStockStatus === self::OutOfStockStatus_VisibleShadow) {
return true;
} else {
return false;
}
}
/**
* @return int
*/
public function getQualityStatus()
{
return $this->qualityStatus;
}
/**
* @param int $qualityStatus
*/
public function setQualityStatus($qualityStatus)
{
$this->qualityStatus = $qualityStatus;
}
/**
* @param $id
* @param TranslatorInterface $translator
* @return int
*/
public function getQualityStatusTitle(?int $id = null, TranslatorInterface $translator = null)
{
if (is_null($id)) {
$id = $this->qualityStatus;
}
if (!is_null($translator)) {
return $translator->trans(self::getQualityStatusChoices()[$id]);
}
return self::getQualityStatusChoices()[$id];
}
/**
* @param string $detail
* @return string
*/
public static function createFormatedDetail($detail)
{
$result = '';
$lines = preg_split('/\\n\\r*/', $detail);
if (count($lines) > 0) {
$result .= '<div class="detail">';
}
$is_list = false;
foreach ($lines as $line) {
$line = trim($line);
$line = str_replace('[b]', '<strong>', $line);
$line = str_replace('[/b]', '</strong>', $line);
$line = str_replace('[bl]', '<span class="blue-text">', $line);
$line = str_replace('[/bl]', '</span>', $line);
$line = str_replace('[r]', '<span class="red-text">', $line);
$line = str_replace('[/r]', '</span>', $line);
if ($line == '') {
$result .= '<br>';
} elseif ($line == '[l]' && !$is_list) {
$result .= '<dl>';
$is_list = true;
} elseif ($line == '[/l]' && $is_list) {
$result .= '</dl>';
$is_list = false;
} elseif ($is_list) {
$result .= '<dt>' . $line . '</dt>';
} else {
$result .= '<p>' . $line . '</p>';
}
}
if (count($lines) > 0) {
$result .= '</div>';
}
return $result;
}
/**
* @param AttributeOption $attributeOption
*
* @return bool
*/
public function hasAttributeOption($attributeOption)
{
/**
* @var AttributeOption $attr
*/
foreach ($this->getSpecificationAttributeOptions() as $attr) {
if ($attr->getId() == $attributeOption->getId()) {
return true;
}
if ($attr->hasParent() && $attr->getParent()->getId() == $attributeOption->getId()) {
return true;
}
}
return false;
}
/**
* @return int
*/
public function getOutOfStockStatus()
{
return $this->outOfStockStatus;
}
/**
* @param int $outOfStockStatus
*/
public function setOutOfStockStatus($outOfStockStatus)
{
$this->outOfStockStatus = $outOfStockStatus;
}
/**
* @param $id
* @return int
*/
public function getOutOfStockStatusTitle($id)
{
return self::getStockStatusChoices()[$id];
}
/**
* @param null $dimension*
* @param null $unit
* Possible units for dimensions: g, dkg, kg, t,
* Possible units for weight: mm, cm, dm, m
* @param bool $includeUnitInName
* @return null|string
*/
public function dimensionInUnit($dimension = null, $unit = null, $includeUnitInName = false)
{
if ($dimension != null && $unit != null) {
switch ($unit) {
case 'g':
$result = $dimension;
break;
case 'dkg':
$result = $dimension / 100;
break;
case 'kg':
$result = $dimension / 1000;
break;
case 't':
$result = $dimension / 10000;
break;
case 'mm':
$result = $dimension;
break;
case 'cm':
$result = $dimension / 10;
break;
case 'dm':
$result = $dimension / 100;
break;
case 'm':
$result = $dimension / 1000;
break;
default:
return null;
}
if ($includeUnitInName) {
return $result . ' ' . $unit;
} else {
return $result;
}
} else {
return null;
}
}
/**
* Returns length dimensions in given unit
*
* @param null $unit
* @param bool $includeUnitInName
* @return null|string
*/
public function dimensions($unit = null, $includeUnitInName = false)
{
$dimensions = '';
if ($unit != null) {
if ($this->getLength() != 0) {
$dimensions .= $this->dimensionInUnit($this->getLength(), $unit, $includeUnitInName);
}
if ($this->getWidth() != 0) {
if ($dimensions != '') {
$dimensions .= ' x ';
}
$dimensions .= $this->dimensionInUnit($this->getWidth(), $unit, $includeUnitInName);
}
if ($this->getLength() != 0) {
if ($dimensions != '') {
$dimensions .= ' x ';
}
$dimensions .= $this->dimensionInUnit($this->getHeight(), $unit, $includeUnitInName);
}
if ($dimensions != '') {
return $dimensions;
} else {
return null;
}
} else {
return null;
}
}
/**
* IF substract sold commission parameter is true, substract commissions with status sold and defined invoice nubmer
* else return full number of commissions
*
* @param bool $subtractReturnedCommissions
* @return Collection
* @internal param bool $subtractSoldCommissions
* @internal param bool $subtractSoldCommissions
*/
public function getCommissions($subtractReturnedCommissions = true)
{
if ($subtractReturnedCommissions) {
$notSoldCommissions = new ArrayCollection();
if (!is_null($this->commissions) && $this->commissions->count() > 0) {
foreach ($this->commissions as $commission) {
if (
$commission->getStatus() == ProductCommission::Status_AtPartner
|| ($commission->getStatus() == ProductCommission::Status_Sold && ($commission->getInvoiceNumber() == '' || $commission->getInvoiceNumber() == null))
) {
$notSoldCommissions->add($commission);
}
}
}
return $notSoldCommissions;
} else {
return $this->commissions;
}
}
/**
* @return int
*/
public function getCommissionCount()
{
$commissions = 0;
if ($this->getCommissions() !== null) {
$commissions = $this->getCommissions()->count();
}
return $commissions;
}
/**
* @param \DateTime|null $dateSince
* @return Collection
*/
public function getOrderItems(?\DateTime $dateSince = null)
{
if (!is_null($this->orderItems) && !is_null($dateSince)) {
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->gt('created', $dateSince));
return $this->orderItems->matching($criteria);
} else {
return $this->orderItems;
}
}
/**
* @return Collection
*/
public function getReservations()
{
$this->reservations = new ArrayCollection();
$reservationsSince = (new \DateTime())->setDate(2016, 12, 2)->setTime(0, 0);
$orderItems = $this->getOrderItems($reservationsSince);
if (!is_null($orderItems)) {
foreach ($orderItems as $orderItem) {
$order = $orderItem->getOrder();
if (
(is_null($order->getInvoiceCode()) || $order->getInvoiceCode() == '')
&& (!is_null($order->getLastStockMovement()) && $order->getLastStockMovement()->getType() != StockMovement::TYPE_OUT)
) {
$this->reservations->add($orderItem);
}
}
}
return $this->reservations;
}
/**
* @return int
*/
public function getReservationsCount()
{
$reservationCount = 0;
foreach ($this->getReservations() as $reservation) {
$reservationCount += $reservation->getQuantity();
}
return $reservationCount;
}
/**
* @return Collection
*/
public function getSold()
{
$sold = new ArrayCollection();
$soldSince = (new \DateTime())->setDate(2016, 12, 2)->setTime(0, 0);
$orderItems = $this->getOrderItems($soldSince);
if (!is_null($orderItems)) {
foreach ($orderItems as $orderItem) {
$order = $orderItem->getOrder();
if (!is_null($order->getLastStockMovement()) && $order->getLastStockMovement()->getType() == StockMovement::TYPE_OUT) {
$sold->add($orderItem);
}
}
}
return $sold;
}
/**
* @return int
*/
public function getSoldCount()
{
$soldCount = 0;
foreach ($this->getSold() as $sold) {
$soldCount += $sold->getQuantity();
}
return $soldCount;
}
public function isShipping()
{
return self::SHIPPING_ID == $this->getId();
}
/**
* @return int
*/
public function getInStock()
{
return $this->inStock;
}
/**
* @param int $inStock
*/
public function setInStock($inStock)
{
$this->inStock = $inStock;
}
/**
* @return boolean
*/
public function isArchived()
{
return $this->archived;
}
/**
* @param boolean $archived
*/
public function setArchived($archived)
{
$this->archived = $archived;
}
/**
* @return boolean
*/
public function isScannable()
{
return $this->scannable;
}
public function isScannableWithType()
{
$isTypeScannable = $this->type ? $this->type->isScannable() : $this->productModel->getType()->isScannable();
return $this->scannable && $isTypeScannable;
}
/**
* @param boolean $scannable
*/
public function setScannable($scannable)
{
$this->scannable = $scannable;
}
/**
* @return Collection
*/
public function getStockMovementItems()
{
return $this->stockMovementItems;
}
/**
* @return StockMovementItem|null
*/
public function getLastStockMovementItem()
{
$stockMovementItems = $this->getStockMovementItems();
return $stockMovementItems->count() > 0 ? $stockMovementItems->first() : null;
}
/**
* @return Collection
*/
public function getProductVariations()
{
return $this->productVariations;
}
/**
* @return boolean
*/
public function isContainer()
{
return $this->container;
}
/**
* @param boolean $container
*/
public function setContainer($container)
{
$this->container = $container;
}
/**
* @return Collection
*/
public function getProductContainers()
{
return $this->productContainers;
}
/**
* @return Collection
*/
public function getChildContainers()
{
return $this->childContainers;
}
/**
* @param Collection $productContainers
*/
public function setProductContainers($productContainers)
{
$this->productContainers = $productContainers;
}
/**
* @return float
*/
public function getLastPrice()
{
return $this->lastPrice;
}
/**
* @param float $lastPrice
*/
public function setLastPrice($lastPrice)
{
$this->lastPrice = $lastPrice;
}
/**
* @return float
*/
public function getAvgPrice()
{
return $this->avgPrice;
}
/**
* @param float $avgPrice
*/
public function setAvgPrice($avgPrice)
{
$this->avgPrice = $avgPrice;
}
/**
* @return Collection
*/
public function getCategoryPages()
{
return $this->categoryPages;
}
/**
* @param Collection $categoryPages
*/
public function setCategoryPages($categoryPages)
{
$this->categoryPages = $categoryPages;
}
/**
* @return string
*/
public function getGtin()
{
return $this->gtin;
}
/**
* @param string $gtin
*/
public function setGtin($gtin)
{
$this->gtin = $gtin;
}
/**
* @return string
*/
public function getAmazonCode()
{
return $this->amazonCode;
}
/**
* @param string $amazonCode
*/
public function setAmazonCode($amazonCode)
{
$this->amazonCode = $amazonCode;
}
/**
* @param ProductTag $tag
*
* @return Product
*/
public function addTag(ProductTag $tag): Product
{
$this->tags[] = $tag;
return $this;
}
/**
* @param ProductTag $tag
*
* @return boolean
*/
public function removeTag(ProductTag $tag): bool
{
return $this->tags->removeElement($tag);
}
/**
* @return Collection
*/
public function getTags()
{
return $this->tags;
}
/**
* @return Collection
*/
public function getNotifications()
{
return $this->notifications;
}
public function getPriceLogs()
{
return $this->priceLogEntries;
}
/**
* @return \DateTime|null
*/
public function getLastSale(): ?\DateTime
{
return $this->lastSale;
}
/**
* @param \DateTime|null $lastSale
*/
public function setLastSale(?\DateTime $lastSale)
{
$this->lastSale = $lastSale;
}
/**
* @param ProductExternalFeedName $externalFeedName
*/
public function addExternalFeedName(ProductExternalFeedName $externalFeedName): void
{
$this->externalFeedNames[] = $externalFeedName;
}
/**
* @param ProductExternalFeedName $externalFeedName
*/
public function removeExternalFeedName(ProductExternalFeedName $externalFeedName): bool
{
return $this->externalFeedNames->removeElement($externalFeedName);
}
/**
* @return Collection
*/
public function getExternalFeedNames(): Collection
{
return $this->externalFeedNames;
}
/**
* @return ?ProductExternalFeedName
*/
public function getExternalFeedNameByLanguage(Language $language)
{
return $this->externalFeedNames->filter(
function (ProductExternalFeedName $feedName) use ($language) {
return $feedName->getLanguage() == $language;
}
)->first();
}
/**
* @return bool
*/
public function containerHasMainProduct(): bool
{
if ($this->isContainer()) {
foreach ($this->getProductContainers() as $productContainer) {
if ($productContainer->getChild() && in_array($productContainer->getProduct()->getType()->getId(), [44, 52, 60])) { // Monitor, Notebook, PC
return true;
}
}
}
return false;
}
/**
* @return bool
*/
public function isMainProduct(): bool
{
return in_array($this->getType()->getId(), ProductType::getMainProductTypeIds());
}
/**
* @param StockMovementItem $stockMovementItem
* @return float
*/
public function getLastPurchasePrice(StockMovementItem $stockMovementItem): float
{
foreach ($this->stockMovementItems as $index => $movementItem) {
if ($movementItem->getId() == $stockMovementItem->getId()) {
// Increase
$increaseWith = 1;
do {
// Previous Stock Movement Item
$previousStockMovementItem = $this->stockMovementItems->get(($index + $increaseWith));
if ($previousStockMovementItem) {
// Need a In Stock Movement
$stockMovement = $previousStockMovementItem->getMovement();
if ($stockMovement->getType() == StockMovement::TYPE_IN) {
// Exchange Currency
$exchangeCurrency = $stockMovement->getMerchant()->getDomain()->getCurrencyTextCode();
// Exchange Rate
$exchangeRate = 1;
if ($exchangeCurrency !== 'EUR') {
$exchangeRate = (float)$stockMovement->getExchangeRate();
}
if ((float)$exchangeRate <= 0) {
$exchangeRate = 1;
}
// Converted Price
return round(($previousStockMovementItem->getTotalPricePerItem() / $exchangeRate), 2);
}
}
// Increase
$increaseWith++;
} while ($previousStockMovementItem);
}
}
return .0;
}
/**
* @param StockMovementItem $stockMovementItem
* @return array
*/
public function getLastPurchasePriceWithCurrency(StockMovementItem $stockMovementItem): array
{
foreach ($this->stockMovementItems as $index => $movementItem) {
if ($movementItem->getId() == $stockMovementItem->getId()) {
// Increase
$increaseWith = 1;
do {
// Previous Stock Movement Item
$previousStockMovementItem = $this->stockMovementItems->get(($index + $increaseWith));
if ($previousStockMovementItem) {
// Need a In Stock Movement
$stockMovement = $previousStockMovementItem->getMovement();
if ($stockMovement->getType() == StockMovement::TYPE_IN) {
return [
'currency' => $stockMovement->getMerchant()->getDomain()->getCurrencyTextCode(),
'value' => $previousStockMovementItem->getTotalPricePerItem(),
];
}
}
// Increase
$increaseWith++;
} while ($previousStockMovementItem);
}
}
return [];
}
/**
* @return int[]
*/
public static function getExcludededProductIdsFromUpdate(): array
{
return [
Product::SHIPPING_ID,
Product::CASH_ON_DELIVERY_PRODUCT_ID,
Product::CABLE_POWER_PRODUCT_ID,
Product::MPL_PACKAGE_FEE_PRODUCT_ID,
];
}
/**
* @return int[]
*/
public static function getExcludededProductTypeIdsFromUpdate(): array
{
return [
ProductType::PRODUCT_TYPE_ID_SERVICE,
];
}
/**
* @return Collection
*/
public function getPopularProductsCategoryPages(): Collection
{
return $this->popularProductsCategoryPages;
}
/**
* @param Collection $popularProductsCategoryPages
*/
public function setPopularProductsCategoryPages(Collection $popularProductsCategoryPages): void
{
$this->popularProductsCategoryPages = $popularProductsCategoryPages;
}
/**
* @return bool
*/
public function isInQuarantine(): bool
{
return (mb_strpos($this->name, 'QUARANTINE @') !== false ? true : false);
}
/**
* @return boolean
*/
public function isUltrabook(): bool
{
if ($this->getWeight() > 1500 || $this->getWeight() == 0) {
return false;
}
if ($this->getHeight() > 20 || $this->getHeight() == 0) {
return false;
}
if (str_contains(strtolower($this->name), 'chromebook')) {
return false;
}
$hasIntelCoreProcessor = $hasSSDAttribute = false;
/**
* @var ProductAttribute $productAttribute
*/
foreach ($this->getConfigurationAttributes() as $productAttribute) {
if (str_contains(strtolower($productAttribute->getOption()->getTitle()), 'intel core')) {
$hasIntelCoreProcessor = true;
}
if ($productAttribute->getOption()->getAttribute()->getId() == Attribute::ATTRIBUTE_ID_SSD) {
$hasSSDAttribute = true;
}
if ($hasIntelCoreProcessor && $hasSSDAttribute) {
return true;
}
}
return $hasIntelCoreProcessor && $hasSSDAttribute;
}
/**
* @return boolean
*/
public function isWindows11Compatible(): bool
{
if (!in_array($this->type->getId(), ProductType::getWindows11CompatibleList())) {
return false;
}
if (in_array('ChromeBook', $this->badges) || str_contains(strtolower($this->getFullTitle()), 'chromebook')) {
return false;
}
if ($this->getVendor()->getName() == 'Apple') {
return false;
}
/**
* @var ProductAttribute $productAttribute
*/
foreach ($this->getConfigurationAttributes() as $productAttribute) {
if ($productAttribute->getOption()->getAttribute()->getId() == Attribute::ATTRIBUTE_ID_CPU_GENERATION) {
$selectedOption = $productAttribute->getOption();
$cpuGenerationNumber = (int) str_replace('. Generation', '', $selectedOption->getTitle());
return $cpuGenerationNumber >= 8;
}
// AMD Processors - https://docs.google.com/spreadsheets/d/1j2CfMFTS19YoPzrD06n3PWQpK_EfJXZKArypPwVQT-w/edit#gid=2081660312
if (in_array($productAttribute->getOption()->getId(), [5276, 5301, 5092, 5094, 5228, 4829, 4830, 4906, 4215, 4228, 4397, 3988, 2682, 2734, 2321, 2323, 2513, 2211])) {
return true;
}
}
return false;
}
/**
* @return bool
*/
public function isTinyPC(): bool
{
return $this->hasBadgeItem(self::PRODUCT_BADGE_TINY_PC);
}
/**
* @return int
*/
public function getCpuMark(): int
{
return $this->cpuMark;
}
/**
* @param int $cpuMark
* @return void
*/
public function setCpuMark(int $cpuMark): void
{
$this->cpuMark = $cpuMark;
}
/**
* @return ProductModel|null
*/
public function getProductModel(): ?ProductModel
{
return $this->productModel;
}
/**
* @param ProductModel|null $productModel
* @return void
*/
public function setProductModel(?ProductModel $productModel): void
{
$this->productModel = $productModel;
}
/**
* @return bool
*/
public function isSparePartCard(): bool
{
return $this->sparePartCard;
}
/**
* @param bool $sparePartCard
* @return void
*/
public function setSparePartCard(bool $sparePartCard): void
{
$this->sparePartCard = $sparePartCard;
}
/**
* @return float|int
*/
public function getSparePartPrice(): float|int
{
return $this->sparePartPrice;
}
/**
* @param float|int $sparePartPrice
* @return void
*/
public function setSparePartPrice(float|int $sparePartPrice): void
{
$this->sparePartPrice = $sparePartPrice;
}
public function getSparePartCreated(): ?\DateTime
{
return $this->sparePartCreated;
}
public function setSparePartCreated(?\DateTime $sparePartCreated): void
{
$this->sparePartCreated = $sparePartCreated;
}
public function getSparePartUpdated(): ?\DateTime
{
return $this->sparePartUpdated;
}
public function setSparePartUpdated(?\DateTime $sparePartUpdated): void
{
$this->sparePartUpdated = $sparePartUpdated;
}
public function getSparePartCreatedBy(): ?User
{
return $this->sparePartCreatedBy;
}
public function setSparePartCreatedBy(?User $sparePartCreatedBy): void
{
$this->sparePartCreatedBy = $sparePartCreatedBy;
}
public function getSparePartUpdatedBy(): ?User
{
return $this->sparePartUpdatedBy;
}
public function setSparePartUpdatedBy(?User $sparePartUpdatedBy): void
{
$this->sparePartUpdatedBy = $sparePartUpdatedBy;
}
/**
* @return int
*/
public function getMarginLevel(): int
{
return $this->marginLevel;
}
/**
* @param int $marginLevel
* @return void
*/
public function setMarginLevel(int $marginLevel): void
{
$this->marginLevel = $marginLevel;
}
/**
* @param float $currentPrice
*
* @return string
*/
public function getCalculatedMarginLevel(float $currentPrice): string
{
if ( $currentPrice <= 0 || $this->avgPrice <= 0 ) {
return self::getMarginLevelChoices()[$this->marginLevel] ?? self::getMarginLevelChoices()[self::MARGIN_LEVEL_NO];
}
if (( $currentPrice - $this->avgPrice ) > 200 ) {
return self::getMarginLevelChoices()[self::MARGIN_LEVEL_A];
}
elseif (( $currentPrice - $this->avgPrice ) > 150 ) {
return self::getMarginLevelChoices()[self::MARGIN_LEVEL_B];
}
elseif (( $currentPrice - $this->avgPrice ) > 100 ) {
return self::getMarginLevelChoices()[self::MARGIN_LEVEL_C];
}
elseif (( $currentPrice - $this->avgPrice ) > 50 ) {
return self::getMarginLevelChoices()[self::MARGIN_LEVEL_D];
}
else {
return self::getMarginLevelChoices()[self::MARGIN_LEVEL_E];
}
}
/**
* @return Collection
*/
public function getCoupons()
{
return $this->coupons;
}
/**
* @param Collection $coupons
* @return void
*/
public function setCoupons(Collection $coupons): void
{
$this->coupons = $coupons;
}
public function getQuantityLimit(): ?int
{
return $this->quantityLimit;
}
public function setQuantityLimit(?int $quantityLimit): void
{
$this->quantityLimit = $quantityLimit;
}
/**
* @return bool
*/
public function isAvailabilityPausedForProductModel(): bool
{
return $this->availabilityPausedForProductModel;
}
/**
* @param bool $availabilityPausedForProductModel
* @return void
*/
public function setAvailabilityPausedForProductModel(bool $availabilityPausedForProductModel): void
{
$this->availabilityPausedForProductModel = $availabilityPausedForProductModel;
}
/**
* @return FixedAttributeOptionCombination
*/
public function getFixedAttributeOptionCombination()
{
return $this->fixedAttributeOptionCombination;
}
/**
* @param FixedAttributeOptionCombination $fixedAttributeOptionCombination
*/
public function setFixedAttributeOptionCombination(FixedAttributeOptionCombination $fixedAttributeOptionCombination)
{
$this->fixedAttributeOptionCombination = $fixedAttributeOptionCombination;
}
/**
* @return \DateTime
*/
public function getLastQtySyncDate(): ?\DateTime
{
return $this->lastQtySyncDate;
}
/**
* @param \DateTime $lastQtySyncDate
*/
public function setLastQtySyncDate(\DateTime $lastQtySyncDate)
{
$this->lastQtySyncDate = $lastQtySyncDate;
}
public function getConnectedBatteries(): array
{
$result = [];
$productModel = $this->getProductModel();
/** @var Product $product */
foreach ($productModel?->getConnectedProducts() ?? [] as $product) {
if ($product->getType()->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK_BATTERY) {
$result[] = $product;
}
}
return $result;
}
public function addConnectedProductModel(ProductModel $productModel): self
{
if (!$this->connectedProductModels->contains($productModel)) {
$this->connectedProductModels->add($productModel);
}
return $this;
}
public function getConnectedProductModels()
{
return $this->connectedProductModels;
}
/**
* @return Collection<int, Product>
*/
public function getAlternativeProducts(): Collection
{
return $this->alternativeProducts;
}
public function addAlternativeProduct(Product $product): self
{
if (!$this->alternativeProducts->contains($product)) {
$this->alternativeProducts->add($product);
}
return $this;
}
public function removeAlternativeProduct(Product $product): self
{
$this->alternativeProducts->removeElement($product);
return $this;
}
/**
* @return Collection<int, Product>
*/
public function getParentAlternativeProducts(): Collection
{
return $this->parentAlternativeProducts;
}
public function getCurrentAlternativeProduct(): ?Product
{
return $this->currentAlternativeProduct;
}
public function setCurrentAlternativeProduct(?Product $currentAlternativeProduct): void
{
$this->currentAlternativeProduct = $currentAlternativeProduct;
}
/**
* @return Collection
*/
public function getCustomerClaimProducts(): Collection
{
return $this->customerClaimProducts;
}
public function addCustomerClaimProduct(CustomerClaimProduct $customerClaimProduct): self
{
if (!$this->customerClaimProducts->contains($customerClaimProduct)) {
$this->customerClaimProducts[] = $customerClaimProduct;
$customerClaimProduct->setProduct($this);
}
return $this;
}
public function removeCustomerClaimProduct(CustomerClaimProduct $customerClaimProduct): self
{
if ($this->customerClaimProducts->removeElement($customerClaimProduct)) {
if ($customerClaimProduct->getProduct() === $this) {
$customerClaimProduct->setProduct(null);
}
}
return $this;
}
/**
* @return int
*/
public function getCalculatedQtyGradeNew()
{
return $this->calculatedQtyGradeNew;
}
/**
* @param int $calculatedQtyGradeNew
*/
public function setCalculatedQtyGradeNew(int $calculatedQtyGradeNew)
{
$this->calculatedQtyGradeNew = $calculatedQtyGradeNew;
}
/**
* @return int
*/
public function getCalculatedQtyGradeA()
{
return $this->calculatedQtyGradeA;
}
/**
* @param int $calculatedQtyGradeA
*/
public function setCalculatedQtyGradeA(int $calculatedQtyGradeA)
{
$this->calculatedQtyGradeA = $calculatedQtyGradeA;
}
/**
* @return int
*/
public function getCalculatedQtyGradeB()
{
return $this->calculatedQtyGradeB;
}
/**
* @param int $calculatedQtyGradeB
*/
public function setCalculatedQtyGradeB(int $calculatedQtyGradeB)
{
$this->calculatedQtyGradeB = $calculatedQtyGradeB;
}
/**
* @return int
*/
public function getCalculatedQtyGradeC()
{
return $this->calculatedQtyGradeC;
}
/**
* @param int $calculatedQtyGradeC
*/
public function setCalculatedQtyGradeC(int $calculatedQtyGradeC)
{
$this->calculatedQtyGradeC = $calculatedQtyGradeC;
}
/**
* @return int
*/
public function getCalculatedQtyGradeD()
{
return $this->calculatedQtyGradeD;
}
/**
* @param int $calculatedQtyGradeD
*/
public function setCalculatedQtyGradeD(int $calculatedQtyGradeD)
{
$this->calculatedQtyGradeD = $calculatedQtyGradeD;
}
/**
* @return bool
*/
public function isMicrosoftOffice(): bool
{
/** @var ProductAttribute $productAttribute */
foreach ($this->productAttributes as $productAttribute) {
if ($productAttribute->getOption()->getId() == AttributeOption::ATTRIBUTE_OPTION_ID_OFFICE && $productAttribute->getOption()->getAttribute()->getId() == Attribute::ATTRIBUTE_ID_SOFTWARE) {
return true;
}
}
return false;
}
/**
* @return bool
*/
public function isBazaar(): bool
{
return $this->qualityStatus === self::QualityStatus_Bazaar;
}
}