*/ #[ORM\OneToMany(mappedBy: 'article', targetEntity: AttributeValue::class, cascade: ['persist', 'remove'])] private Collection $attributeValues; /** @var Collection */ #[ORM\OneToMany(mappedBy: 'article', targetEntity: ArticlePhoto::class, cascade: ['persist', 'remove'])] #[ORM\OrderBy(['sortOrder' => 'ASC'])] private Collection $photos; public function __construct( ArticleType $articleType, string $sku, string $inventoryNumber, int $stock, ArticleCondition $condition, ) { $this->id = Uuid::v7(); $this->articleType = $articleType; $this->sku = $sku; $this->inventoryNumber = $inventoryNumber; $this->status = ArticleStatus::Ingesting; $this->stock = $stock; $this->condition = $condition; $this->attributeValues = new ArrayCollection(); $this->photos = new ArrayCollection(); } public function transitionTo(ArticleStatus $newStatus): void { if (!$this->status->canTransitionTo($newStatus)) { throw new \DomainException(\sprintf('Cannot transition from %s to %s', $this->status->value, $newStatus->value)); } $this->status = $newStatus; } public function decrementStock(): void { if ($this->stock <= 0) { throw new \DomainException('Stock cannot go below zero'); } --$this->stock; } public function isOutOfStock(): bool { return 0 === $this->stock; } public function getMainPhoto(): ?ArticlePhoto { foreach ($this->photos as $photo) { if ($photo->isMain()) { return $photo; } } return null; } public function getId(): Uuid { return $this->id; } public function getArticleType(): ArticleType { return $this->articleType; } public function getSku(): string { return $this->sku; } public function getInventoryNumber(): string { return $this->inventoryNumber; } public function getStatus(): ArticleStatus { return $this->status; } public function getStock(): int { return $this->stock; } public function getCondition(): ArticleCondition { return $this->condition; } public function getConditionNotes(): ?string { return $this->conditionNotes; } public function getListingPrice(): ?string { return $this->listingPrice; } public function getSerialNumber(): ?string { return $this->serialNumber; } public function getEbayListingId(): ?string { return $this->ebayListingId; } public function getEbayTitle(): ?string { return $this->ebayTitle; } public function getEbayDescription(): ?string { return $this->ebayDescription; } public function setAttributeValue(AttributeValue $value): void { foreach ($this->attributeValues as $existing) { if ($existing->getAttributeDefinition()->getId()->equals($value->getAttributeDefinition()->getId())) { $this->attributeValues->removeElement($existing); break; } } $this->attributeValues->add($value); } /** @return Collection */ public function getAttributeValues(): Collection { return $this->attributeValues; } /** @return Collection */ public function getPhotos(): Collection { return $this->photos; } public function setConditionNotes(?string $notes): void { $this->conditionNotes = $notes; } public function setListingPrice(?string $price): void { $this->listingPrice = $price; } public function setSerialNumber(?string $sn): void { $this->serialNumber = $sn; } public function setEbayListingId(?string $id): void { $this->ebayListingId = $id; } public function setEbayTitle(?string $title): void { $this->ebayTitle = $title; } public function setEbayDescription(?string $desc): void { $this->ebayDescription = $desc; } }