true])] private bool $active = true; /** @var Collection */ #[ORM\OneToMany(targetEntity: PackageService::class, mappedBy: 'package', cascade: ['persist', 'remove'], orphanRemoval: true)] private Collection $services; #[ORM\Column(name: 'created_at', type: 'integer')] private int $createdAt; #[ORM\Column(name: 'updated_at', type: 'integer')] private int $updatedAt; public function __construct(string $entityType, int $entityId, string $name, int $sessionCount) { $this->uuid = Uuid::v4()->toRfc4122(); $this->name = $name; $this->sessionCount = max(1, $sessionCount); $this->services = new ArrayCollection(); $this->createdAt = time(); $this->updatedAt = time(); $this->assignTenantPair($entityType, $entityId); } public function getId(): ?int { return $this->id; } public function getUuid(): string { return $this->uuid; } public function getName(): string { return $this->name; } public function getSessionCount(): int { return $this->sessionCount; } public function getPriceRials(): int { return (int) $this->priceRials; } public function getValidityDays(): ?int { return $this->validityDays; } public function isActive(): bool { return $this->active; } public function getCreatedAt(): int { return $this->createdAt; } /** @return Collection */ public function getServices(): Collection { return $this->services; } public function setName(string $v): self { $this->name = $v; return $this->touch(); } public function setSessionCount(int $v): self { $this->sessionCount = max(1, $v); return $this->touch(); } public function setPriceRials(int $v): self { $this->priceRials = max(0, $v); return $this->touch(); } public function setValidityDays(?int $v): self { $this->validityDays = $v === null ? null : max(1, $v); return $this->touch(); } public function setActive(bool $v): self { $this->active = $v; return $this->touch(); } public function addService(PackageService $service): self { if (!$this->services->contains($service)) { $this->services->add($service); } return $this; } /** تاریخ انقضای یک خرید در این لحظه — `null` یعنی بی‌پایان. */ public function expiryFor(int $purchasedAt): ?int { return $this->validityDays === null ? null : $purchasedAt + $this->validityDays * 86400; } /** @return list شناسهٔ سرویس‌های پوشش‌داده‌شده */ public function serviceIds(): array { return array_values(array_map( static fn (PackageService $s): int => (int) $s->getServiceItem()->getId(), $this->services->toArray(), )); } private function touch(): self { $this->updatedAt = time(); return $this; } /** @return array */ public function toArray(): array { return [ 'uuid' => $this->uuid, 'name' => $this->name, 'session_count' => $this->sessionCount, 'price_rials' => (int) $this->priceRials, 'validity_days' => $this->validityDays, 'active' => $this->active, 'services' => array_values(array_map( static fn (PackageService $s): array => [ 'uuid' => $s->getServiceItem()->getUuid(), 'name' => $s->getServiceItem()->getName(), ], $this->services->toArray(), )), 'created_at' => $this->createdAt, ]; } }