<?php
namespace App\AtechNet\CoreBundle\Entity;
use App\AtechNet\CoreBundle\Repository\PersonalizationAttributeOptionCombinationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\JoinTable;
use Doctrine\ORM\Mapping\ManyToMany;
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\PersistentCollection;
/**
* @Table(name="personalization_attribute_option_combinations")
* @Entity(repositoryClass=PersonalizationAttributeOptionCombinationRepository::class)
*/
class PersonalizationAttributeOptionCombination extends AbstractSignedEntity
{
public const TOTAL_NONE_COMBINATION_ID = 22080;
public const array ATTRIBUTE_ORDERING_MAP = [
V2Attribute::ID_OS,
V2Attribute::ID_OS_LANGUAGE,
V2Attribute::ID_KEYBOARD_REPRINT,
V2Attribute::ID_SKIN,
];
public const array NONE_ATTRIBUTE_OPTIONS = [
V2AttributeOption::OPTION_ID_OS_NONE,
V2AttributeOption::OPTION_ID_OS_LANGUAGE_NONE,
V2AttributeOption::OPTION_ID_KEYBOARD_REPRINT_NONE,
V2AttributeOption::OPTION_ID_SKIN_NONE,
];
/**
* @var PersistentCollection
*
* @ManyToMany(targetEntity="V2AttributeOption", inversedBy="personalizationAttributeOptionCombinations")
* @JoinTable(
* name="personalization_attribute_option_combination_attribute_options",
* joinColumns={
* @JoinColumn(name="personalization_attribute_option_combination_id", referencedColumnName="id", onDelete="CASCADE")
* },
* inverseJoinColumns={
* @JoinColumn(name="v2_attribute_option_id", referencedColumnName="id")
* })
* @OrderBy({"created" = "DESC"})
*/
private $attributeOptions;
/**
* @var string
*
* @Column(name="code", type="string", unique=true, nullable=true)
*/
private string $code;
/**
* @var PersistentCollection
*
* @OneToMany(targetEntity="StockMovementItem", mappedBy="personalizationAttributeOptionCombination")
*/
private $stockMovementItems;
/**
* @var PersistentCollection
*
* @OneToMany(targetEntity="OrderItem", mappedBy="personalizationAttributeOptionCombination")
*/
private $orderItems;
public function __construct()
{
parent::__construct();
$this->attributeOptions = new ArrayCollection();
$this->stockMovementItems = new ArrayCollection();
$this->orderItems = new ArrayCollection();
}
public function getAttributeOptions(): ?PersistentCollection
{
return $this->attributeOptions;
}
public function setAttributeOptions(ArrayCollection $attributeOptions): void
{
$this->attributeOptions = $attributeOptions;
}
public function addAttributeOption(V2AttributeOption $attributeOption): void
{
if (!$this->attributeOptions->contains($attributeOption)) {
$this->attributeOptions->add($attributeOption);
}
}
public function removeItem(V2AttributeOption $attributeOption): void
{
$this->attributeOptions->removeElement($attributeOption);
}
public function getCode(): string
{
return $this->code;
}
public function setCode(string $code): void
{
$this->code = $code;
}
public function getSortedAttributeOptions(): ArrayCollection
{
$orderMap = array_flip(self::ATTRIBUTE_ORDERING_MAP);
$options = $this->getAttributeOptions()->toArray();
usort($options, function ($a, $b) use ($orderMap) {
$aKey = $orderMap[$a->getV2Attribute()->getId()] ?? PHP_INT_MAX;
$bKey = $orderMap[$b->getV2Attribute()->getId()] ?? PHP_INT_MAX;
return $aKey <=> $bKey;
});
return new ArrayCollection($options);
}
public function getSortedAttributeOptionsAsDisplayName(string $separator = '|'): string
{
$options = $this->getSortedAttributeOptions();
$names = [];
/** @var V2AttributeOption $option */
foreach ($options as $option) {
$names[] = $option->getDisplayFormattedValue();
}
return implode(" $separator ", $names);
}
/**
* @param string $separator
* @return string
*/
public function getSortedAttributeOptionsWithAttributeNameAsDisplayName(string $separator = '|'): string
{
$options = $this->getSortedAttributeOptions();
$names = [];
/** @var V2AttributeOption $option */
foreach ($options as $option) {
$unit = $option->getUnit()?->getDisplayName();
$names[] = trim($option->getV2Attribute()->getTitle() . ' ' . $option->getValue() . ' ' . $unit);
}
return implode(" $separator ", $names);
}
public function getAttributeOptionIds(): array
{
return $this->getAttributeOptions()
->map(fn (V2AttributeOption $o) => $o->getId())
->toArray();
}
public function getOptionByAttributeId(int $v2AttributeId): ?V2AttributeOption
{
$result = $this->getAttributeOptions()->filter(
fn (V2AttributeOption $vao) => $vao->getV2Attribute()->getId() === $v2AttributeId
)->first();
return $result ?: null;
}
public function getStockMovementItems(): ArrayCollection
{
return $this->stockMovementItems;
}
public function addStockMovementItem(StockMovementItem $stockMovementItem): void
{
if (!$this->stockMovementItems->contains($stockMovementItem)) {
$this->stockMovementItems->add($stockMovementItem);
}
}
public function removeStockMovementItem(StockMovementItem $stockMovementItem): void
{
$this->stockMovementItems->removeElement($stockMovementItem);
}
public function getOrderItems(): ArrayCollection
{
return $this->orderItems;
}
public function addOrderItem(OrderItem $orderItem): void
{
if (!$this->orderItems->contains($orderItem)) {
$this->orderItems->add($orderItem);
}
}
public function removeOrderItem(OrderItem $orderItem): void
{
$this->orderItems->removeElement($orderItem);
}
/**
* Returns options that differ between this and another combination, keyed by attribute ID.
* Each entry: ['self' => V2AttributeOption|null, 'other' => V2AttributeOption|null]
*
* @return array<int, array{self: V2AttributeOption|null, other: V2AttributeOption|null}>
*/
public function getDifferingOptions(?PersonalizationAttributeOptionCombination $other): array
{
$selfMap = [];
$otherMap = [];
if (!$other) {
return [];
}
/** @var V2AttributeOption $option */
foreach ($this->getAttributeOptions() ?? [] as $option) {
$selfMap[$option->getV2Attribute()->getId()] = $option;
}
/** @var V2AttributeOption $option */
foreach ($other->getAttributeOptions() ?? [] as $option) {
$otherMap[$option->getV2Attribute()->getId()] = $option;
}
$allAttributeIds = array_unique(array_merge(array_keys($selfMap), array_keys($otherMap)));
$differences = [];
foreach ($allAttributeIds as $attrId) {
/** @var V2AttributeOption|null $selfOption */
$selfOption = $selfMap[$attrId] ?? null;
/** @var V2AttributeOption|null $otherOption */
$otherOption = $otherMap[$attrId] ?? null;
if ($selfOption?->getId() !== $otherOption?->getId()) {
$differences[$attrId] = [
'self' => $selfOption,
'other' => $otherOption,
];
}
}
return $differences;
}
}