Przejdź do głównej zawartości

Indywidualne Cenniki Rezerwacji (Individual Reservation Pricing)

1. Instrukcja Użytkownika (User Manual)

Cel i Wartość Biznesowa (Purpose & Business Value)

Moduł indywidualnych cenników rezerwacji pozwala administratorom na elastyczne definiowanie stawek dla wybranych klientów. Zamiast standardowych, globalnych cen przypisanych do obiektów lub typów zajęć, wybrany klient może otrzymać dedykowany cennik na rezerwacje (np. kortów).

Funkcja ta wspiera zarówno proste rabaty (np. stała niższa cena za godzinę), jak i zaawansowane reguły rozliczeniowe (np. inne stawki w weekendy, w określonych godzinach szczytu lub w wyznaczonych przedziałach dat).

Główne Funkcje (Key Features)

  1. Wybór trybu cennika: Na profilu użytkownika w zakładce Ustawienia administrator może włączyć indywidualną cenę rezerwacji i wybrać jeden z dwóch trybów:
    • Podstawowy (Stała cena): Klient płaci stałą, określoną kwotę za każdą godzinę rezerwacji (np. zawsze 50 zł/h).
    • Zaawansowany (Reguły cenowe): Pozwala na zdefiniowanie dynamicznych reguł, analogicznie do konfiguracji cenników typów zajęć.
  2. Kreator reguł zaawansowanych: W trybie zaawansowanym administrator może dodać wiele reguł określających:
    • Zakresy dat obowiązywania reguły (np. sezon letni).
    • Dni tygodnia (np. tylko weekendy).
    • Przedziały godzinowe (np. godziny wieczorne od 16:00 do 22:00).
    • Cenę obowiązującą w wybranym przedziale.
  3. Cena bazowa: W trybie zaawansowanym definiuje się również cenę bazową, która obowiązuje w okresach nieobjętych żadną szczegółową regułą.

2. Dokumentacja Techniczna (Technical Documentation)

Model Danych i Schemat Bazy (Data Model & Schema)

Ustawienia klienta są przechowywane w tabeli client_settings. Do obsługi zaawansowanych cenników dodano dwa nowe pola w ramach migracji 0114_add_individual_pricing_rules_to_client_settings.sql:

  • individual_reservation_pricing_type (TEXT, domyślnie 'basic'): Określa tryb cennika ('basic' lub 'advanced').
  • individual_reservation_pricing_rules (TEXT, domyślnie NULL): Przechowuje reguły w formacie JSON (tablica obiektów typu PricingRule).
ALTER TABLE client_settings ADD COLUMN individual_reservation_pricing_type TEXT DEFAULT 'basic';
ALTER TABLE client_settings ADD COLUMN individual_reservation_pricing_rules TEXT DEFAULT NULL;

Przepływ Obliczania Ceny (Pricing Resolution Flow)

  1. Pobieranie ustawień: Metoda getClientSettingsForUser(userEmail) pobiera z bazy danych rekord z tabeli client_settings i deserializuje reguły zapisane w formacie JSON do typu PricingRule[].
  2. Aplikowanie nadpisania ceny: W pliku lib/utils/client-pricing.ts funkcja applyClientPricingOverride obsługuje kalkulację dla aktywności typu booking (rezerwacje):
    • Jeżeli klient ma ustawiony tryb 'advanced' i zdefiniowane reguły, system przypisuje te reguły do właściwości pricing_rules obiektu wynikowego, a cenę bazową ustawia jako price.
    • Główny silnik wyliczania cen (calculatePrice) przetwarza następnie te reguły w kontekście konkretnej daty i godziny rezerwacji, uwzględniając dni tygodnia oraz przedziały godzinowe.
    • Jeżeli klient ma ustawiony tryb 'basic', stosowana jest stała wartość individual_reservation_price.

Priorytety i Nadpisywanie (Precedence & Overrides)

W systemie obowiązuje następująca kolejność wyliczania stawek (od najwyższego priorytetu):

  1. Dedykowany cennik klienta dla konkretnego typu zajęć (tabela client_pricing_rules) – jeśli zdefiniowano regułę dla danej aktywności i danego użytkownika, ma ona pierwszeństwo.
  2. Indywidualny cennik rezerwacji klienta (ustawienia z tabeli client_settings) – zaawansowane reguły lub cena podstawowa (tylko dla aktywności typu booking).
  3. Standardowy cennik typu zajęć – cennik domyślny przypisany globalnie do rezerwacji/zajęć.

Testowanie i Atrapy SQLite (Testing & SQLite Mocks)

Ze względu na to, że testy integracyjne korzystają z lokalnych mocków bazy danych SQLite, w plikach testowych zdefiniowane są statyczne schematy tabel. Wszystkie mocki tabeli client_settings w poniższych plikach testowych zostały zaktualizowane o nowe kolumny:

Nowe przypadki testowe weryfikujące poprawność rozstrzygania reguł zostały dodane w dedykowanym pliku: