Kasa klubowa
Widok Kasa (/dashboard/cash) oraz kafelek „Kasa klubowa" w panelu bocznym grafiku pokazują, ile pieniędzy powinno znajdować się w szufladzie kasowej danej lokalizacji.
👤 Instrukcja dla pracownika
Co oznacza „Aktualny stan kasy klubowej"
Jest to suma narastająca od początku działalności lokalizacji, a nie stan dnia czy zmiany. System liczy ją tak:
sprzedaż sklepowa gotówką + transakcje opłacone gotówką − wypłaty z kasy + wpłaty do kasy
Analogicznie liczony jest stan dla płatności kartą. Nie ma tu żadnego „zamknięcia dnia" — jeśli ktoś wyjmie pieniądze z szuflady bez zarejestrowania wypłaty, saldo w systemie przestanie zgadzać się ze stanem faktycznym.
Kasa jest zawsze przypisana do lokalizacji
Stan kasy dotyczy tej lokalizacji, którą masz wybraną w selektorze u góry ekranu:
- wybrane konkretne miasto i ulica → widzisz kasę tej jednej lokalizacji,
- wybrane miasto bez podziału na ulice (np. Lublin) → widzisz kasę całego miasta,
- wybrane Wszystkie miasta → widzisz sumę zbiorczą ze wszystkich lokalizacji.
Wypłata i wpłata zawsze trafiają do lokalizacji widocznej na ekranie. Jedyny wyjątek: gdy masz wybrane „Wszystkie miasta", system nie wie, o którą kasę chodzi, i zapisuje operację do lokalizacji domyślnej. Przed rejestrowaniem wypłaty upewnij się więc, że masz wybrane konkretne miasto.
Częste pytania
Dlaczego kwota na grafiku różni się od tej w zakładce Kasa? Nie powinna — oba miejsca liczą to samo dla tej samej lokalizacji. Jeśli się różnią, sprawdź, czy w obu miejscach masz wybrane to samo miasto.
Dlaczego „Ostatnia aktualizacja" pokazuje bieżącą godzinę? To znacznik momentu pobrania danych, a nie ostatniej operacji na kasie. Saldo jest przeliczane przy każdym wejściu na stronę.
🛠 Dokumentacja techniczna
Przepływ danych
Źródło lokalizacji
resolveReadLocation(city, street) w lib/actions/court.ts jest jedynym miejscem, w którym selekcja z URL zamienia się na filtr odczytu:
citypuste lub'ALL'→{ city: 'ALL', street: 'ALL' }, czyli brak filtrowania,- brak
streetw URL →getDefaultStreetForCity(city), które zwraca konkretną ulicę wyłącznie dla miast wielolokalizacyjnych, - miasto jednolokalizacyjne →
street: 'ALL', bo takie miasta nie mają wymiaru ulicy.
Każdy odczyt musi przechodzić przez ten helper. CashManagementWrapper dokleja rozwiązaną lokalizację do zapytań /api/cash-management (query dla GET, body dla POST), dzięki czemu odświeżenie po wypłacie trafia dokładnie w tę samą lokalizację, którą wyrenderował SSR.
Ciasteczka selected-city / selected-street pozostają wyłącznie fallbackiem dla wywołań bez jawnej lokalizacji. Są globalne dla przeglądarki, więc przy dwóch kartach z różnymi lokalizacjami nie są wiarygodne — nie opieraj na nich nowych odczytów.
Filtrowanie w SQL
locationFilter(loc, alias?) (lib/utils/location-filter.ts) buduje fragment AND city = ? AND street = ?, pomijając wymiar o wartości 'ALL' lub pustej. getCashBalance używa trzech wariantów:
| Wariant | Tabela | Alias |
|---|---|---|
salesFilter | sales | brak |
payFilter | payment | p |
cwFilter | cash_withdrawal | brak |
linked_payment celowo nie ma własnych kolumn lokalizacji — płatności dzielone są filtrowane przez JOIN do płatności nadrzędnej (p), z której dziedziczą lokalizację.
Zapis lokalizacji
resolveWriteLocation(location?)— dla operacji inicjowanych z UI.'ALL'zwija się do lokalizacji domyślnej, bo nie jest poprawnym celem zapisu.getWriteStreetForCity(city)— dla rekordów, których miasto wynika z danych (terminy obozów i kursów, płatności pochodne). Zwraca ulicę domyślną tylko dla miast wielolokalizacyjnych, a dla pozostałych pusty string.
Kolumny city / street w payment, sales i cash_withdrawal są NOT NULL DEFAULT 'Opole' / 'Spokojna'. Pominięcie ich w INSERT nie powoduje błędu — rekord po cichu wyląduje w lokalizacji domyślnej. Każdy nowy INSERT do tych tabel musi jawnie ustawiać lokalizację.
Uwagi do interpretacji salda
- Saldo jest sumą narastającą — brak zakresu dat i brak zamknięcia dnia.
last_updatedtonew Date()z momentu zapytania, nie znacznik ostatniej operacji.- Płatności ze statusem
refundedlubfunds_retained = 1z metodą gotówkową powiększają stan kasy: środki zostają w klubie (zwrot idzie na portfel), więc gotówka fizycznie nie opuszcza szuflady. Ta sama konwencja obowiązuje wlib/actions/finances.ts.