---
title: "Dostupnosť a sloty — Opening Hours for Laravel | Roundly"
description: "Overte, či sa dá termín rezervovať, a vypíšte voľné sloty — s kapacitou, časovými rezervami, predstihom a horizontom z akéhokoľvek zdroja."
url: https://roundly-consulting.com/sk/open-source/navody/opening-hours-for-laravel/dostupnost-a-sloty
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Opening Hours for Laravel](https://roundly-consulting.com/sk/open-source/navody/opening-hours-for-laravel.md)

# Dostupnosť a sloty

Dostupnosť nevie nič o rezerváciách — pýta sa zdroja obsadenosti, čo je obsadené. availability() vráti nemenný builder; každý setter vráti kópiu:

```php
use Carbon\CarbonImmutable;
use RoundlyConsulting\OpeningHours\Availability\BusyPeriod;
use RoundlyConsulting\OpeningHours\Facades\OpeningHours;

$availability = OpeningHours::for($clinic)->availability()
    ->withBusyPeriods(fn (CarbonImmutable $start, CarbonImmutable $end) => $bookings->between($start, $end))
    ->capacity(2)                           // parallel bookings (a range's own capacity wins)
    ->buffers(before: 5, after: 10)         // must fall inside opening hours by default
    ->minNotice(minutes: 120)
    ->horizon(days: 60);

$result = $availability->check($start, $end);   // AvailabilityResult
$result->available;                             // bool
$result->reason;                                // ?UnavailableReason: invalid_range, in_past, too_soon, too_far, closed, busy
$result->conflict;                              // ?BusyPeriod
$result->message();                             // translated reason
$availability->isAvailable($start, $end, weight: 1);
```

## Nastavenia

| Metóda | Význam |
| --- | --- |
| `withBusyPeriods($busy)` | Zdroj obsadenosti: BusyPeriodProvider, iterable s BusyPeriod alebo closure (start, end), ktorá ich vráti. |
| `capacity(int)` | Predvolená paralelná kapacita (≥ 1); vlastná kapacita rozsahu má prednosť; inak 1. |
| `buffers(before:, after:, withinOpeningHours: true)` | Minúty blokované okolo každej rezervácie; predvolene musia spadať do otváracích hodín. Pri withinOpeningHours: false sa zatvorená časť rezervy počíta s kapacitou rozsahu, v ktorom rezervácia začína (before) alebo končí (after). |
| `minNotice(minutes:)` | Najskorší začiatok = teraz + n skutočných minút. |
| `horizon(days:)` | Najneskorší začiatok = teraz + n kalendárnych dní podľa miestneho času (vrátane); null = bez limitu. |
| `at($instant)` | Vyhodnotiť k tomuto okamihu namiesto teraz. |

## Prečo termín nie je dostupný

check() vyhodnocuje v pevnom poradí a vráti prvý dôvod zlyhania; message() ho vráti preložený:

| Dôvod | Kedy |
| --- | --- |
| `invalid_range` | Koniec nie je po začiatku. |
| `in_past` | Začiatok je v minulosti. |
| `too_soon` | Začiatok spadá do minimálneho predstihu. |
| `too_far` | Začiatok je za horizontom. |
| `closed` | Otváracie hodiny nepokrývajú rezerváciu aj s časovými rezervami. |
| `busy` | Kapacita je niekde v obsadenom okne prekročená; conflict obsahuje prvé prekrývajúce sa obsadené obdobie. |

## Sloty

```php
$slots = $availability->slots('2026-10-01', '2026-10-07')     // whole local days, inclusive
    ->duration(30)->step(15)->alignTo(15)
    ->limit(200)
    ->get();                                                   // SlotCollection
$slots->groupByDate();                                         // ['2026-10-01' => [Slot, …], …]

foreach ($slots as $slot) {
    $slot->start;                                              // CarbonImmutable
    $slot->end;
    $slot->remainingCapacity;
}

$all = $availability->slots('2026-10-01', '2026-10-01')
    ->duration(60)
    ->includeUnavailable()                                     // also slots that failed on capacity
    ->get();
$all->available();                                             // only the bookable ones

$availability->slots('2026-10-01', '2026-10-01')->duration(60)->first();   // ?Slot
$availability->nextAvailableSlot(duration: 30);                // ?Slot
$availability->freePeriods('2026-10-01', '2026-10-01');        // list<Period>
```

- slots($from, $to) prijíma dátumy (celé miestne dni vrátane) alebo okamihy (koniec vylúčený). duration() je povinné; step() je predvolene rovné dĺžke; alignTo() je predvolene rovné kroku a počíta sa od miestnej polnoci.
- weight() rezervuje naraz viac jednotiek kapacity; includeUnavailable() vráti aj sloty, ktoré zlyhali na kapacite (dôvod busy); limit() obmedzí výsledok na limits.slots.
- get() vráti SlotCollection — bežnú kolekciu s pridanými metódami available() a groupByDate(), takže map(), groupBy(), keyBy() či pluck() fungujú ako zvyčajne; first() vráti prvý ?Slot.
- Každý Slot má start, end, available, remainingCapacity a reason. Je Arrayable aj JsonSerializable: toArray(), json\_encode() aj response()->json() vrátia start, end, available, remaining\_capacity a reason s časmi v ISO-8601 vo výstupnom pásme — a SlotCollection takto vráti každý slot so zachovanými kľúčmi.
- nextAvailableSlot() prezerá search\_days miestnych dní dopredu a vráti slot, ktorý by slots() nad tým istým oknom uviedol ako prvý. Hľadá po častiach, takže sa sám zmestí do max\_query\_days — QueryRangeTooLargeException vyhodí, len ak je jeden slot aj s časovými rezervami dlhší.
- Mriežka sa zarovnáva podľa miestneho času a ostáva správna aj pri preskočenej či zopakovanej hodine a 30-minútových posunoch; viacdňové sloty (prenájmy) fungujú rovnako.

## Model kapacity

Kapacita otvorenia je range.capacity ?? kapacita dostupnosti ?? 1, pričom prekrývajúce sa rozsahy berú maximum. Rezervácia sa zmestí, ak usage + weight ≤ capacity v každom okamihu \[start − before, end + after). Toto okno sa musí zmestiť do max\_query\_days: check(), isAvailable() aj dotazy na sloty pri dlhšom okne vyhodia QueryRangeTooLargeException ešte pred načítaním hodín či obsadených období. Pri buffers(withinOpeningHours: false) sa zatvorená časť rezervy počíta s kapacitou rozsahu, v ktorom rezervácia začína (before) alebo končí (after). Dĺžka, predstih aj časové rezervy sú skutočný uplynulý čas; horizont sa počíta v kalendárnych dňoch podľa miestneho času.

## Pri rezervácii overte znova

Dostupnosť je iba čítanie. Keď rezerváciu ukladáte, overte ju znova vo vlastnom zámku alebo cez unikátne obmedzenie — medzi kontrolou a zápisom môže ten istý slot rezervovať iný request:

```php
use Illuminate\Support\Facades\Cache;

Cache::lock("book:{$vet->id}:{$start}", 10)->block(5, function () use ($availability, $vet, $start, $end): void {
    abort_unless($availability->isAvailable($start, $end), 409);

    Appointment::query()->create(['vet_id' => $vet->id, 'starts_at' => $start, 'ends_at' => $end]);
});
```

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/opening-hours-for-laravel.md)
