Skip to main content

Raporty finansowe i transakcje

Instrukcja dotycząca zakładki Finanse w systemie. Znajdziesz tu informacje o tym, jak system zlicza wpłaty od klientów i jak ułatwia rozliczanie kasy na koniec zmiany.

👤 Instrukcja dla pracownika

Zakładka Finanse (dostępna w głównym menu) służy do monitorowania wszystkich przychodów obiektu. Pozwala na łatwe podsumowanie zmiany i sprawdzenie, ile pieniędzy wpłynęło gotówką, a ile kartą lub przelewami online.

1. Grupowanie transakcji (Jedna wpłata = Jeden wiersz)

W systemie wdrożyliśmy ułatwienie polegające na grupowaniu płatności. Co to oznacza dla Ciebie?

  • Kiedyś, jeśli klient płacił z góry za 4 lekcje w miesiącu, system pokazywał to jako 4 osobne wpłaty na liście.
  • Obecnie: Jeśli klient zapłacił za cały pakiet jedną kartą, w kasie, jednym przelewem lub otrzymał na to jedną fakturę – zobaczysz to w zakładce Finanse jako jeden wiersz.
  • W opisie takiej płatności zobaczysz skrót, np. Zajęcia: Szkoła (x4).
  • Dzięki temu liczba transakcji w systemie idealnie zgadza się z liczbą paragonów z kasy fiskalnej lub raportem z terminala, co bardzo ułatwia zamykanie zmiany.

2. Karty podsumowań (Kafelki na górze ekranu)

Na górze zakładki Finanse znajdziesz kafelki z sumami:

  • Łączny przychód – suma wszystkich opłaconych transakcji z wybranego okresu.
  • Gotówka / Karta / Online / Portfel – rozbicie przychodów na konkretne metody płatności.
  • Licznik transakcji przy każdej metodzie (np. "Gotówka: 15 transakcji") pokazuje, ile razy fizycznie przyjęto zapłatę tą metodą.

3. Płatności Mieszane (Gotówka + Karta)

Jeśli przyjmiesz od klienta płatność "mieszaną" (np. za zajęcia warte 100 zł klient daje 50 zł w gotówce, a resztę dopłaca kartą na terminalu):

  • System w finansach rozbije tę transakcję poprawnie.
  • Kwota 50 zł zasili kafelek podsumowujący "Gotówkę", a 50 zł kafelek "Karta".
  • Gdy przefiltrujesz listę tylko dla transakcji gotówkowych, wpłata mieszana pojawi się tam, ale z uwzględnieniem tylko jej gotówkowej części.

4. Podział przychodów na kategorie

Oprócz podziału na metody płatności, przychody dzielone są na kategorie sprzedaży (wynajem kortów, lekcje indywidualne/grupowe, półkolonie, gastronomia, vouchery itd.). Kafelek „Przychody wg kategorii” oraz filtr „Kategorie przychodów” pozwalają sprawdzić, za co wpłynęły pieniądze. Szczegóły i tabelę warunków opisano w rozdziale Kategorie przychodów.


🛠️ Dokumentacja techniczna

Poniższa sekcja wyjaśnia mechanikę agregacji transakcji na poziomie kodu (in-memory grouping) dla deweloperów.

Architektura i algorytm grupowania

Dane o płatnościach są pobierane z tabeli payment. W celu unifikacji wierszy w jedną transakcję bez utraty danych pobocznych (np. zniżek), grupowanie odbywa się w pamięci przy użyciu funkcji pomocniczej groupAndMergePayments w pliku lib/actions/finances.ts.

Klucze Grupowania (Grouping Keys)

Rekordy płatności przypisywane są do grup na podstawie kryteriów (według priorytetów):

  1. Online (Session ID): Płatności z tym samym niepustym session_id (zintegrowane z bramką Przelewy24).
  2. Kasa fiskalna (Receipt ID): Płatności z tym samym niepustym receipt_id.
  3. Fakturownia (Invoice ID): Płatności z tym samym niepustym invoice_id.
  4. Płatności bezpośrednie w klubie: Płatności posiadające identyczny paid_at (znacznik czasu, z dokładnością co do sekundy), tę samą metodę płatności oraz status (np. zbiorcze rozliczenie gotówkowe na recepcji).
  5. Pozostałe: Każda płatność oczekująca, lub niemająca powyższych identyfikatorów, jest renderowana jako osobna transakcja.

Agregacja Wierszy (Row Merging)

Gdy rekordy trafiają do jednej grupy, ich pola są łączone:

  • amount: Suma wartości wszystkich płatności w grupie.
  • playerName: Połączona unikalna lista graczy (rozdzielona przecinkami).
  • activityType: Połączona lista typów aktywności.
  • description: Otrzymuje sufiks (x[liczba_wierszy]) jeśli opisy są spójne, w przeciwnym razie jest listą opartą o przecinki.
  • Karty benefitowe: Sumowanie identyfikatorów zniżek z kart typu Multisport/Medicover.
  • Płatności mieszane: Obiekt rozbija się na mixedPaymentCashAmount oraz mixedPaymentCardAmount.

Flow w API / Server Actions

  1. getFinancialTransactions:
    • Wyciąga pełną pulę rekordów pasującą do filtrów dat/użytkowników.
    • Puszcza je przez groupAndMergePayments.
    • Dołącza ewentualne transakcje ze sklepu (Sale).
    • Sortuje czasowo, a na samym końcu nakłada paginację na poziomie tablicy w pamięci (offset, limit).
  2. getFinancialSummary:
    • Strona /dashboard/finances pobiera pełną pulę transakcji raz i przekazuje ją tu jako preloadedTransactions, dzięki czemu podsumowanie nie odpytuje bazy ponownie o te same rekordy.
    • Zapytania o karty benefitowe i rozliczenia linked_payment są wykonywane jednym db.batch([...]) zamiast trzech osobnych round-tripów.
    • Iteruje i uzupełnia liczniki (agregaty gotówkowe, prowizje itd.) prezentowane w kafelkach UI.

Odporność na przeciążenie bazy (D1)

Zapytania do D1 na ścieżkach renderowania stron finansów i płatności są opakowane w withD1Retry (lib/d1-retry.ts): przejściowe błędy typu D1 DB is overloaded. Too many requests queued. są ponawiane do 3 razy z rosnącym opóźnieniem i losowym jitterem, zamiast natychmiast wywracać render strony.