*/ final readonly class GetAvailableTimeslotsQuery implements Query { private const int TIMESLOTS_DAY_TARGET = 28; public function __construct( private readonly PickupSchedulingService $pickupService, private readonly ShopRepository $shopRepository ) { } public function __invoke(QueryInput $input): GetAvailableTimeslotsQueryOutput { Assert::isAOf( $input, GetAvailableTimeslotsQueryInput::class, ); $domainShop = $this->shopRepository->find($input->forShop); /** @var \Domain\Models\ValueObjects\PickupTimeSlot[] */ $timeslotList = []; if ($domainShop !== null) { $timeslotList = $this->pickupService->getTimeSlotsFor( $domainShop, $this->getUntil() ); } return new GetAvailableTimeslotsQueryOutput( timeslotList: $timeslotList ); } private function getUntil(): CarbonInterface { return CarbonImmutable::now()->addDays(self::TIMESLOTS_DAY_TARGET); } }