*/ final readonly class Campaign implements AggregateRoot, HasTimestampIdentifier { private function __construct( public CampaignId $id, public CampaignCode $code, public Tag $tag, public CampaignName $name, public bool $publication, public bool $printAllAtOnce, public Country $availableIn, /** @var array $coupons */ public array $coupons, public BrandCode $brand, public ?\DateTimeInterface $updatedAt = null, ) { foreach ($this->coupons as $coupon) { if (!$coupon instanceof CampaignCoupon) { throw new \DomainException('Campaign coupons must be CampaignCoupon instances.'); } } } public function id(): CampaignId { return $this->id; } public function createdAt(): \DateTimeInterface { return $this->id->toDateTime(); } public function updatedAt(): ?\DateTimeInterface { return $this->updatedAt; } /** * @param array $coupons */ public static function create( CampaignCode $code, Tag $tag, CampaignName $name, bool $publication, bool $printAllAtOnce, Country $availableIn, /** @var array $coupons */ array $coupons, BrandCode $brand, ?\DateTimeInterface $updatedAt = null, ): Campaign { return new self( id: CampaignId::generate(), code: $code, tag: $tag, name: $name, publication: $publication, printAllAtOnce: $printAllAtOnce, availableIn: $availableIn, coupons: $coupons, brand: $brand, updatedAt: $updatedAt, ); } /** * @param array $coupons */ public static function hydrate( CampaignId $id, CampaignCode $code, Tag $tag, CampaignName $name, bool $publication, bool $printAllAtOnce, Country $availableIn, array $coupons, BrandCode $brand, ?\DateTimeInterface $updatedAt = null, ): self { return new self( id: $id, code: $code, tag: $tag, name: $name, publication: $publication, printAllAtOnce: $printAllAtOnce, availableIn: $availableIn, coupons: $coupons, brand: $brand, updatedAt: $updatedAt, ); } }