start; } /** * Slot end instant (UTC). */ public function end(): DateTimeImmutable { return $this->end; } /** * Assigned agent id, if any. */ public function agent_id(): ?int { return $this->agent_id; } /** * Location id, if any. */ public function location_id(): ?int { return $this->location_id; } /** * Total capacity for this start. */ public function capacity_total(): int { return $this->capacity_total; } /** * Remaining capacity for this start. */ public function capacity_remaining(): int { return $this->capacity_remaining; } /** * Whether the slot is bookable. */ public function is_available(): bool { return $this->is_available; } /** * Reason when the slot is unavailable. */ public function unavailable_reason(): ?BusyReason { return $this->unavailable_reason; } /** * Return a copy with a different agent id. * * @param int $agent_id Agent id. */ public function with_agent_id( int $agent_id ): self { return new self( $this->start, $this->end, $agent_id, $this->location_id, $this->capacity_total, $this->capacity_remaining, $this->is_available, $this->unavailable_reason ); } /** * Return a copy with updated capacity figures. * * @param int $total Total capacity. * @param int $remaining Remaining capacity. */ public function with_capacity( int $total, int $remaining ): self { return new self( $this->start, $this->end, $this->agent_id, $this->location_id, $total, $remaining, $remaining > 0 && $this->is_available, $remaining > 0 ? $this->unavailable_reason : BusyReason::Capacity ); } }