Skip to content

Kalendář

Cesta: / nebo /Calendar
Komponenta: src/pages/Calendar.jsx
Role: Admin

Centrální rozhraní aplikace. Slouží ke správě všech termínů, blokací a dovolených.

Pohledy

Pohled Popis
Týdenní — terapeuté Každý terapeut má vlastní sloupec, zobrazuje celý tým najednou
Týdenní — místnosti Každá místnost jako sloupec, viditelnost obsazenosti prostor
Měsíční přehled Přehled termínů v rámci měsíce
Agenda Seřazený seznam nadcházejících termínů

Funkce

  • Kliknutí na volný slot → otevře EventDialog s předvyplněným časem, terapeutem a místností
  • Drag & drop pro přesunutí termínu na jiný čas
  • Filtry: výběr konkrétních terapeutů a místností v postranním panelu
  • Detekce konfliktů v reálném čase (překryv termínů, kapacita místnosti)
  • Automatické logování všech změn do ActivityLog

EventDialog — vytvoření termínu

Nejkomplexnější komponenta aplikace (src/components/calendar/EventDialog.jsx).

Workflow

flowchart TD
    A[Klik na slot v kalendáři] --> B[Otevře EventDialog]
    B --> C[Výběr typu: termín / blokace / dovolená]
    C --> D[Výběr data a terapeuta]
    D --> E[Výpočet volných slotů]
    E --> F[Výběr výkonu a slotu]
    F --> G[Výběr místnosti]
    G --> H[Výběr klienta — povinné pro termín]
    H --> I[Uložení → CalendarEvent.create]
    I --> J[ActivityLog záznam]
    J --> K{Nový termín?}
    K -- ano --> L[PaymentMethodDialog — volba způsobu úhrady]
    K -- ne --> M[Konec]

Změna logiky (export 19. 8. 2026): po uložení termínu se místo prosté nabídky platebního odkazu otevře PaymentMethodDialog, který ukazuje všechny dostupné způsoby úhrady i jejich hodnotu:

  • čerpat z balíčku (se zbývajícím počtem sezení)
  • zaplatit kreditem (zůstatek vs. cena)
  • výzva k platbě (e-mail / odkaz klientovi, nově i SMS)
  • platba na místě — hotovost nebo karta na recepci, s ID transakce pro spárování (internal_payment_id)

U výkonů s is_insurance se fáze platby přeskočí úplně — rezervace vznikne s payment_method = 'insurance' a klient neplatí.

Vedle toho je v dialogu BookingLinkBox s veřejným rezervačním odkazem podle vybraného výkonu a terapeuta (/client?service=…&therapist=…) a u zaplacených termínů RefundDialog pro vratku.

Logika volných slotů

Pro každý AvailabilityBlock terapeuta na dané datum:
  1. Filtr podle service_types (pokud vybrán výkon)
  2. Generuj sloty po 30 min od start_time do end_time − duration
  3. Vyřaď sloty s konfliktem (překryv s existujícími CalendarEvent)
  4. Zobraz jen :00 a :30 sloty (čistší UX)

Ruční mód: Admin může přepnout na ruční zadání časů — obejde logiku volných slotů.

Validace před uložením

  • Povinná pole (terapeut, datum, čas, klient pro appointment)
  • Konflikt s existující událostí terapeuta
  • Kapacita místnosti (room.capacity)
  • Zda termín leží v aktivním AvailabilityBlock

Typy událostí

Typ Popis
appointment Termín s klientem — vyžaduje klienta, výkon
blockage Blokace terapeuta (osobní, administrativa)
vacation Dovolená — může být celodenní

Stavy termínu

reservedconfirmedcompleted

Alternativní stavy: excused, no_show_paid, no_show_unpaid, no_show_insurance, cancelled, cancelled_late, auto_cancelled_unpaid

Poznámka: stav paid byl z enumu status odebrán už dřív. Zaplacení se sleduje výhradně polem payment_status (unpaid / pending / paid / refunded / partially_refunded).

Nedostavil se — storno pojišťovna (nové)

Ověřený fakt — stav no_show_insurance se nabízí jen u klientů ve skupině s is_insurance na výkonu s is_insurance. Backend (clientBooking, akce process_insurance_no_show):

  1. nastaví termín i rezervaci na no_show_insurance a payment_status = 'unpaid'
  2. spočítá stornopoplatek z SystemSettings.insurance_cancellation_fee (default 1 000 Kč)
  3. odešle klientovi e-mail (volitelně SMS) s odkazem /storno?token=… k úhradě
  4. po zaplacení (confirm_insurance_cancellation_fee_payment) vystaví doklad typu penalty

Změna logiky: poplatek nese klient, i když samotný výkon hradí pojišťovna a klient za něj neplatí nic.

Účetní návaznost stavů

Změna logiky: stav termínu nově spouští účetní akci na pozadí (Base44 entitní automat):

Přechod Automat Účetní dopad
completed onServiceRealized vznik výnosu, případně doklad k dodávce nebo marketingový náklad
cancelled_late onLateCancellation storno poplatek (document_type = penalty)

Samotný způsob označení termínu v UI se nezměnil.