|null $meta Meta. * @param DateTimeImmutable $created_at Created UTC. * @param DateTimeImmutable $updated_at Updated UTC. * @param DateTimeImmutable|null $deleted_at Soft delete. * * @throws \Bookline\Domain\Shared\DomainException When invariants fail. */ public function __construct( private ?int $id, private Uuid $uuid, private ?int $wp_user_id, private string $first_name, private ?string $last_name, private EmailAddress $email, private ?DateTimeImmutable $email_verified_at, private ?PhoneNumber $phone, private ?DateTimeImmutable $phone_verified_at, private ?TimeZoneId $timezone, private ?string $locale, private ?string $notes, private bool $marketing_consent, private ?DateTimeImmutable $consent_recorded_at, private CustomerStatus $status, private ?array $meta, private DateTimeImmutable $created_at, private DateTimeImmutable $updated_at, private ?DateTimeImmutable $deleted_at = null, ) { if ( '' === trim( $this->first_name ) ) { throw new DomainException( 'customer.first_name', 'First name must not be empty.' ); } if ( null !== $this->wp_user_id && $this->wp_user_id < 1 ) { throw new DomainException( 'customer.wp_user_id', 'wp_user_id must be positive when set.' ); } if ( $this->marketing_consent && null === $this->consent_recorded_at ) { throw new DomainException( 'customer.consent_timestamp', 'Marketing consent requires consent_recorded_at.' ); } } /** * Database id. * * @since 0.1.0 */ public function id(): ?int { return $this->id; } /** * Public UUID. * * @since 0.1.0 */ public function uuid(): Uuid { return $this->uuid; } /** * Wp user id. * * @since 0.1.0 */ public function wp_user_id(): ?int { return $this->wp_user_id; } /** * First name. * * @since 0.1.0 */ public function first_name(): string { return $this->first_name; } /** * Last name. * * @since 0.1.0 */ public function last_name(): ?string { return $this->last_name; } /** * Email. * * @since 0.1.0 */ public function email(): EmailAddress { return $this->email; } /** * Email verified at. * * @since 0.1.0 */ public function email_verified_at(): ?DateTimeImmutable { return $this->email_verified_at; } /** * Phone. * * @since 0.1.0 */ public function phone(): ?PhoneNumber { return $this->phone; } /** * Phone verified at. * * @since 0.1.0 */ public function phone_verified_at(): ?DateTimeImmutable { return $this->phone_verified_at; } /** * Timezone. * * @since 0.1.0 */ public function timezone(): ?TimeZoneId { return $this->timezone; } /** * Locale. * * @since 0.1.0 */ public function locale(): ?string { return $this->locale; } /** * Notes. * * @since 0.1.0 */ public function notes(): ?string { return $this->notes; } /** * Marketing consent. * * @since 0.1.0 */ public function marketing_consent(): bool { return $this->marketing_consent; } /** * Consent recorded at. * * @since 0.1.0 */ public function consent_recorded_at(): ?DateTimeImmutable { return $this->consent_recorded_at; } /** * Status. * * @since 0.1.0 */ public function status(): CustomerStatus { return $this->status; } /** * Opaque meta payload. * * @return array|null * * @since 0.1.0 */ public function meta(): ?array { return $this->meta; } /** * Created at. * * @since 0.1.0 */ public function created_at(): DateTimeImmutable { return $this->created_at; } /** * Updated at. * * @since 0.1.0 */ public function updated_at(): DateTimeImmutable { return $this->updated_at; } /** * Deleted at. * * @since 0.1.0 */ public function deleted_at(): ?DateTimeImmutable { return $this->deleted_at; } /** * Whether soft-deleted. * * @since 0.1.0 */ public function is_deleted(): bool { return null !== $this->deleted_at; } /** * Is email verified. * * @since 0.1.0 */ public function is_email_verified(): bool { return null !== $this->email_verified_at; } /** * Assign the database id after insert. * * @param int $id New id. * * @throws \Bookline\Domain\Shared\DomainException When id is already set or invalid. * * @since 0.1.0 */ public function assign_id( int $id ): void { if ( null !== $this->id ) { throw new DomainException( 'customer.id_assigned', 'Customer id is already assigned.' ); } $this->id = $id; } /** * Constructor. * * @param DateTimeImmutable $when Deletion instant UTC. * * @since 0.1.0 */ public function soft_delete( DateTimeImmutable $when ): void { if ( null !== $this->deleted_at ) { return; } $this->deleted_at = $when; $this->updated_at = $when; } }