Szybki start
📁 Baza dokumentów
🔔 Alerty
Ładowanie...
⏱ Godziny pracy dostawców
Start = pierwsze kliknięcie „Wyruszam na załadunek" danego dnia (whDepartures). Koniec = ostatnia zaliczona dostawa + 30 min (auto-zamknięcie dniówki). 🚚 w Uwagach = czas od „Wyruszam" do potwierdzenia załadunku — 🔴 przy 60+ min (podejrzenie klikania startu przed realnym wyjazdem). Zapisy są automatyczne z aplikacji dostawcy — do porównania z tym, co raportują.
🏠 Dojazd do domu (eksperyment V530) = szacunkowy czas jazdy wg trasy (Google) z ostatniego zaliczonego punktu dnia do domu kierowcy — na razie tylko informacyjnie, obok sztywnych +30 min; policz przyciskiem, także wstecz dla minionych miesięcy.
🏠 Dojazd do domu (eksperyment V530) = szacunkowy czas jazdy wg trasy (Google) z ostatniego zaliczonego punktu dnia do domu kierowcy — na razie tylko informacyjnie, obok sztywnych +30 min; policz przyciskiem, także wstecz dla minionych miesięcy.
Ładowanie...
📈 Analityka
📦 Zamówienia:
👔 Zespół handlowców
Klik w handlowca → pełny dashboard pracy
💰 Rentowność zespołu
👔
—
—
🔥 Pilne dziś0
📅 Wizyty0
🎁 Próbki rozdane0
💼 Klienci0
💰 Sprzedaż0 zł
⛔ Odmowy0
📋 Taski0
📝 Notatki0
💵 Zaległe płatności klientów0
Zakres dat zamówienia:
od
do
🚐 Zakres dat dostawy:
od
do
| Nr | Klient | 👔 Handlowiec | Złożone | Dostawa | Status | Płatność | Dostawca | Kwota | 📊 Marża | 💰 Profit | Akcje |
|---|
STATUS:
TRYB:
DOSTAWA:
od
do
📊 Estymacja wpływówŁączna kwota proform i FV oczekujących na wpłatę, pogrupowana wg terminu
| Numer | Typ | Klient | Wystawiona | Termin | Pozostało dni | Kwota | Wpłacono | Status | Powiązane | Wezwania | Akcje |
|---|
Zamówienie
⚖️ Dłużnicy — zarządzanie zaległościami
📉 Zaległość łączna — dzień po dniu
Krzywa liczona z terminów płatności i dat wpłat. FV opłacone bez zapisanej daty wpłaty nie zawyżają historii (przyjmują datę terminu).
📊 Zaległość / obrót firmy (%) obrót brutto narastająco w wybranym okresie
💰 Nieopłacone vs obrót — po miesiącach sprzedaż z zamówień miesiąca (brutto, bez anulowanych, po korektach) · z tego kwota DZIŚ nieopłacona · % udział
👔 Handlowcy — zaległość vs obrót vs marża (zaległość: stan dziś wg opiekuna klienta · obrót/marża: wybrany okres)
📋 Lista dłużników
Nowy task
| Nr | Produkt | Kategoria | Warianty | VAT | Magazyn | 📊 Marża / Narzut | Akcje |
|---|
🏭 Magazyn — stany i dokumenty
Stany w jednostkach bazowych produktu (szt./kg — wg karty produktu). Wartość magazynu = ilość × koszt nabycia z karty produktu (netto, waluty po NBP). Dokumenty magazynowe są ilościowe; koszty partii z PZ (cena zakupu + transport) trzymane osobno, tylko dla admina i administracji. Pozycje PZ z ceną tworzą partie FIFO — sprzedaż konsumuje je po kolei i rentowność każdego zamówienia liczy koszt jego konkretnych partii (bez uśredniania; karta produktu = tylko fallback i wycena stanów). Korekta stanu: dokument INW — dokumentów się nie kasuje. Od V535 dostawy zdejmują stan automatycznie (dokument WZ-AUTO/<FR> przy statusie „Dostarczone", z pozycji faktycznie wydanych) — ręczne WZ tylko dla wydań poza zamówieniami, żeby nie zdejmować dwa razy.
🚗 Magazyn podręczny (bagażnik) — osobisty magazyn handlowca/dostawcy. Tworzony automatycznie przy dodaniu nowego użytkownika z rolą handlowiec/dostawca; dla istniejących utwórz poniżej. Towar do bagażnika wjeżdża dokumentem MM (przesunięcie z magazynu głównego). Handlowiec widzi swój bagażnik w swoim panelu (Konto → 📦 Mój bagażnik).
| Klient | NIP | Miasto | Handlowiec | Kredyt (zł) | Typ FV | Konto B2B | Dodano | Akcje |
|---|
Tworzysz tu konta dla całego zespołu: handlowców, administracji, dostawców oraz klientów B2B. Konto Firebase Auth + wpis w kartotece powstają automatycznie.
| Imię / Nazwa | Rola | Status | Dodano | Reads (7d avg) | Akcje |
|---|
🔄 Zastępstwa handlowców
Gdy jeden handlowiec jest na urlopie/L4, drugi może obsługiwać jego klientów. Zastępstwo działa w wybranym zakresie dat. Klienci nie zmieniają opiekuna, ale zastępca widzi ich w swoim panelu i może składać zamówienia/wizyty w ich imieniu. Konwersja i statystyki nadal liczą się oryginalnemu opiekunowi.
🚐 Zastępstwa dostawców
Kierowca na urlopie? Wyznacz zastępcę (innego dostawcę lub handlowca) na wybrany zakres dni. Niezrealizowane dostawy z tych dni zostaną przepisane na zastępcę, awizacja go nazwie, a gotówka pójdzie na jego konto. Zastępca-handlowiec loguje się do panelu dostawcy (/dostawca.html) — ma tam pełną optymalizację trasy. Zastępstwo kończy się samo w dniu „do".
💰 Koszty zespołu handlowego (per miesiąc)
Wprowadzaj miesięczne koszty per handlowiec (pensja, samochód, paliwo, inne). Na podstawie tych danych CRM liczy profit = marża sprzedaży − koszty − próbki dla każdego handlowca. Brak wpisu → 0 zł, fallback do poprzedniego miesiąca.
🚐 Koszty zespołu dostawczego (per miesiąc)
Wpisz stawkę godzinową, premię dzienną (za rozpoczęcie dniówki), premię sobotnią oraz koszt 1 km (paliwo + amortyzacja razem). System liczy koszt całego dnia jako:
(loadedAt → deliveredAt + 1h) × stawka + km × stawka/km + premie, a potem dzieli proporcjonalnie do liczby punktów dostawy. Liczbę km dla danego dnia możesz wpisać w karcie zamówienia (pole dayDistanceKm) lub pozostawić 0.🏪 Typy lokali
Handlowcy wybierają typ lokalu z tej listy przy dodawaniu nowego klienta. Pomaga segmentować bazę (kawiarnia/restauracja/hotel...) i analizować sprzedaż per typ.
👤 Role kontaktu
Handlowcy wybierają rolę osoby kontaktowej z tej listy (Właściciel/Manager/Barista/Kucharz...). Listę można rozszerzać o role specyficzne dla branży klientów.
↪ Przepisz klientów handlowca
⚠ Akcja masowa, nieodwracalna. Używaj gdy handlowiec odchodzi/zmienia rejon. Wszyscy jego klienci zostaną przepisani do drugiego handlowca. Statystyki historyczne pozostają u oryginalnego opiekuna; nowe wizyty i zamówienia są przypisywane do nowego.
🗺️ Planer spotkań — Zwiad mapy
Fundament planera tras handlowców (v501): zasysanie punktów POI (restauracje, hotele, sale zabaw…) z Google Places do naszej bazy. Codzienny planer (v502) będzie czytał wyłącznie z naszej bazy — zero wywołań Google przy generowaniu tras. Zwiad ma twardy miesięczny limit wywołań poniżej darmowego progu Google — po jego osiągnięciu sam się zatrzymuje (koszt: 0 zł). Punkty pokrywające się z istniejącymi klientami dostają status klient (nie trafią do planera), sieciówki z listy wykluczeń — status wykluczony. Zamknięte na stałe lokale są pomijane.
⭐ Jakość punktów (opinie Google)
Trasy zwiadu POMIJAJĄ punkty z oceną poniżej progu lub zbyt małą liczbą opinii. Punkty bez danych z Google (stare skany) przechodzą — dociągną ocenę przy odświeżeniu miasta. Penetracja miast liczy się od pełnej bazy jak dotąd.
⚙️ Konfiguracja zwiadu
Miasta / obszary (1 na linię)
Kategorie (fraza = zapytanie do Google, np. „sala zabaw Katowice")
🔍 = skanuj do mapy · 🧭 = obejmuj zwiadem handlowców (odznacz np. cukiernie — zostaną na mapie, ale nie trafią na trasy ani do penetracji)
| 🔍 Skan mapy | 🧭 Trasy zwiadu | Nazwa | Fraza |
|---|
Wykluczenia — sieciówki (fragment nazwy, 1 na linię)
Franczyzy lokalne (Da Grasso, Zahir Kebab itp.) celowo zostawione w grze — dopisz tu, jeśli chcesz je wyciąć.
Limity miesięczne API (bezpiecznik kosztowy)
Wyszukiwania:
Szczegóły:
Darmowe progi Google: 5000 wyszukiwań i 1000 szczegółów miesięcznie. Limity trzymaj PONIŻEJ — wtedy koszt zawsze 0 zł.
🛰️ Uruchom zwiad
📊 Raport dzienny zwiadu — handlowcy w terenie
📍 Baza punktów
Wybierz miasto lub status i kliknij „Załaduj". Zmiana miasta/statusu wymaga ponownego „Załaduj"; kategoria, szukajka i „podejrzane" filtrują na żywo.
| Punkt | Kategorie | Miasto | Status | Dopasowanie do klienta | Akcje |
|---|
🔢 Numeracja dokumentów
Serie numeracji jak w Optimie: symbol + format per typ dokumentu. Tokeny formatu: NNNN = licznik (liczba N = szerokość zer), MM = miesiąc, RRRR/RR = rok, SYMBOL = symbol serii. Reszta znaków (np.
/) dosłownie. Typ dokumentu bez aktywnej serii numeruje się po staremu — nic się nie zmienia, dopóki nie skonfigurujesz.| Typ | Symbol | Nazwa | Format | Podgląd | Reset | Domyślna | Status | Akcje |
|---|
💡 FV z datą wsteczną / osobna pula: nie zmieniaj formatu istniejącej serii w trakcie roku (jest blokowany po pierwszym użyciu) — dodaj nową serię z własnym symbolem, ustaw ją jako domyślną, wystaw dokument, przełącz domyślną z powrotem.
ℹ Numer zamówienia FR/RRRR/MM/NNNN oraz WZ do zamówienia (pochodna numeru FR) są systemowe i nie podlegają konfiguracji.
ℹ Numer zamówienia FR/RRRR/MM/NNNN oraz WZ do zamówienia (pochodna numeru FR) są systemowe i nie podlegają konfiguracji.
📚 Biblioteki słownikowe
Listy Typów lokali (Kawiarnia, Restauracja...) oraz Ról kontaktu (Właściciel, Manager, Barista...) są edytowalne w sekcji Zespół. Tam też zarządzasz substytucjami i kosztami handlowców/dostawców.
Magazyny
Magazyny służą do grupowania produktów przy planowaniu załadunku kierowcy (jeden kierowca, jeden magazyn).
| Kod | Nazwa | Adres | Produktów | Akcje |
|---|
🚚 Przewoźnicy zewnętrzni
Firmy transportowe do obsługi dostaw paletowych przez Transport Zewnętrzny. Kinga wybiera przewoźnika z tej listy podczas planowania dostawy. Domyślną cenę można zmienić per zlecenie.
| Nazwa | Kontakt | Cena dom. | Lead | Status | Akcje |
|---|
💌 Mailing płatności (przypomnienia o przeterminowanych FV)
System automatycznie wysyła maile do klientów: T-1 (gdy oryginalny termin >3 dni), T+2, T+7, T+14, oraz 4b dzień po przedłużonym terminie, T+30 wezwanie, T+45 ostateczne przedsądowe. Scheduled o 7:00 codziennie.
Dopóki włączony tryb testowy, klienci NIC nie dostają. Po wyłączeniu maile lecą do klientów.
💾 Backupy (kopie off-site — Cloudflare R2)
Codziennie o 02:00 pełny snapshot CRM (Firestore + pliki Storage) ląduje w buckecie foodoro-crm-backups (jurysdykcja UE). Rotacja: 30 dziennych / 12 tygodniowych / 24 miesięczne. Niezależnie działają: PITR (cofnięcie bazy do 7 dni), Delete Protection i managed backupy Firestore.
Restore (3 ścieżki): 1) drobna wpadka z ost. 7 dni → PITR w konsoli GCP; 2) cała baza → managed backup Firestore (konsola → Disaster Recovery); 3) totalna utrata Google → pobierz
firestore.json.gz + folder storage/ z R2 (panel Cloudflare) i odtwórz.
🔐 Migracje bezpieczeństwa kosztów (V369)
Koszty produktów i koszt próbek przeniesione do osobnej kolekcji product_costs (widzą i edytują admin + Kinga; handlowiec/klient nie widzą). Po wgraniu tej wersji uruchom obie migracje raz (są bezpieczne, idempotentne — można klikać wielokrotnie; masz backupy/PITR). A domyka wyciek z produktów, B z historycznych zamówień i wizyt.
A: kopiuje koszty produktu + koszt próbek do
product_costs/{id} i usuwa je z dokumentu produktu (na produkcie zostają tylko nazwy próbek). B: usuwa unitCostSnapshot z pozycji zamówień oraz koszt próbki z wizyt (rentowność liczy bieżący koszt — patrz ostrzeżenie przy edycji produktu).
📨 Maile powiadomień (powiadomienia@foodoro.pl)
Z tej skrzynki lecą: potwierdzenie zrealizowanej dostawy do klienta (lista produktów, zdjęcia, kto odebrał, podpis, kwota; przy gotówce — kwota + imię i nazwisko dostawcy) oraz ostrzeżenie do administracji, gdy klient nie ma adresu e-mail (handlowiec + Kinga).
Dopóki włączony, klient NIE dostaje potwierdzenia dostawy (idzie testowo do Ciebie i Kingi). Ostrzeżenia „klient bez maila" lecą do administracji niezależnie od trybu.
🚚 Czasy trasy (estymacja planu dostaw)
Wpływają na szacowany czas trasy u dostawcy. Czas jazdy liczy Google (free-flow, bez korków); poniżej ustawiasz postoje. Trasa liczona jest: dom → magazyn(y) → klienci → powrót do domu.
Palety Foodoro liczą dodatkowo +90 min/paletę (osobno). Magazyn z własnym czasem (pickupDurationMin) nadpisuje wartość globalną. Zmiana działa przy następnym „Optymalizuj trasę" u dostawcy.
Kategorie produktów
Kategorie tworzą drzewko o dowolnej głębokości, np. Kawa › Ziarna › Brazylia › Świeża. Przy każdej kategorii użyj „+ podkategoria" aby dodać poziom niżej. Struktura może być rozszerzana również z poziomu dodawania produktu.
⛔ Limit dostaw dziennie — panel klienta
Klient B2B nie widzi liczby dostaw. Gdy na dany dzień jest już zaplanowanych tyle dostaw kierowcą (bez anulowanych, bez samoodbioru/przewoźnika/„ja dostarczam"), dzień świeci mu się na czerwono i nie da się na niego zamówić dostawy kierowcą. Handlowca i Kingi limit nie blokuje — oni widzą obłożenie.
Poniżej tej kwoty netto klient nie złoży zamówienia w panelu (przycisk wygaszony, komunikat ile brakuje). 0 = bez minimum. Handlowca i Kingi nie dotyczy.
🛠 Historia w panelu klienta. Zamówienia, faktury i korekty składane/wystawiane zanim klient dostał konto B2B nie miały znacznika konta i były dla niego niewidoczne. Od v595 serwer dokleja go automatycznie; ten przycisk naprawia wszystko wstecz dla wszystkich klientów z kontem. Uruchom raz.
🔗 Adres panelu klienta (linki aktywacyjne, e-maile)
Adres, który klient dostaje w mailu z linkiem do ustawienia hasła i jako powrót po ustawieniu hasła. Domyślnie
https://crm-foodoro-v2.web.app/klient.html. Po podpięciu własnej domeny (np. https://panel.foodoro.pl) wpisz ją tutaj — musi być też dodana w Firebase Auth → Authorized domains, inaczej link wróci na adres domyślny.🚐 Domyślny dostawca
Wybierz kierowcę, do którego będą automatycznie trafiały nowe zamówienia od klientów (z limitu lub gotówką). Zamówienia na przelew (oczekujące na płatność) NIE są przypisywane automatycznie — przypisują się dopiero po zaksięgowaniu wpłaty przez Kingę/Admina.
🛠 Naprawa danych — Zombie faktury
Co to robi: jednorazowo naprawia historyczne niespójności w bazie:
1. Anulowane zamówienia z niezamkniętymi fakturami — gdy zamówienie ma status „Anulowane", ale powiązana proforma/FV nadal ma status unpaid (i świeci na czerwono w panelu Kingi).
→ Naprawa: faktury zostaną oznaczone jako cancelled z notatką „Backfill v256 — zamówienie było anulowane".
2. Faktury VAT wystawione mimo opłaconej proformy — gdy klient zapłacił proformę, a Kinga potem wystawiła FV (która jest unpaid mimo, że klient już zapłacił = podwójne księgowanie długu).
→ Naprawa: FV zostanie oznaczona jako paid ze źródłem „proforma-coverage-backfill" i odwołaniem do proformy.
Bezpieczeństwo: przed wykonaniem zobaczysz listę dokumentów do naprawy i potwierdzasz. Wszystko jest logowane do
1. Anulowane zamówienia z niezamkniętymi fakturami — gdy zamówienie ma status „Anulowane", ale powiązana proforma/FV nadal ma status unpaid (i świeci na czerwono w panelu Kingi).
→ Naprawa: faktury zostaną oznaczone jako cancelled z notatką „Backfill v256 — zamówienie było anulowane".
2. Faktury VAT wystawione mimo opłaconej proformy — gdy klient zapłacił proformę, a Kinga potem wystawiła FV (która jest unpaid mimo, że klient już zapłacił = podwójne księgowanie długu).
→ Naprawa: FV zostanie oznaczona jako paid ze źródłem „proforma-coverage-backfill" i odwołaniem do proformy.
Bezpieczeństwo: przed wykonaniem zobaczysz listę dokumentów do naprawy i potwierdzasz. Wszystko jest logowane do
payments_audit (kolekcja zawierająca historię zmian; nadaje się do rekonstrukcji w razie potrzeby).
🚨 Naprawa danych — Duplikaty CRM-owych FV (bug v257-)
Co to robi: naprawia bug który był aktywny do v257 — automatyczne wystawianie FV ze strony CRM.
Mechanika buga: przycisk „📅 FV zbiorcze miesięczne" (Kinga / Admin) generował automatycznie numer FV w formacie
• CRM-owy duplikat (np.
• Prawdziwy z KSeF (np.
Identyfikacja duplikatów: CRM-owy FV uznajemy za duplikat gdy istnieje INNA paid/unpaid FV od Kingi (manual) z tym samym
Naprawa:
OD v258 nie powstają nowe duplikaty — przycisk „FV zbiorcze miesięczne" teraz otwiera modal kolejkowy, w którym Kinga wpisuje numer KSeF dla każdego klienta osobno.
Mechanika buga: przycisk „📅 FV zbiorcze miesięczne" (Kinga / Admin) generował automatycznie numer FV w formacie
FV/YYYY/MM/NNNN (CRM-owy) i zapisywał invoice w bazie BEZ pytania o numer KSeF. Gdy Kinga potem wgrywała PRAWDZIWĄ FV z KSeF do tego samego klienta — powstawały 2 dokumenty w bazie:• CRM-owy duplikat (np.
FV/2026/05/0001) z generatedBy: 'kinga_monthly_batch'• Prawdziwy z KSeF (np.
189/05/2026/REST) z generatedBy: 'kinga_manual_v170'Identyfikacja duplikatów: CRM-owy FV uznajemy za duplikat gdy istnieje INNA paid/unpaid FV od Kingi (manual) z tym samym
clientId i pokrywającymi się aggregatedOrderIds.Naprawa:
- CRM-owy duplikat → cancelled z reason „Backfill v258 — duplikat CRM zastąpiony FV z KSeF"
- Zamówienia (orderIds) →
fvInvoiceIdprzepisany na prawdziwą FV z KSeF - Log w
payments_auditz pełną informacją (ID duplikatu, ID prawdziwej, numer, klient, kwota)
OD v258 nie powstają nowe duplikaty — przycisk „FV zbiorcze miesięczne" teraz otwiera modal kolejkowy, w którym Kinga wpisuje numer KSeF dla każdego klienta osobno.
🔬 Pogłębiony audyt (V259): jeśli powyższy backfill nic nie znajdzie, ale podejrzewasz że istnieją inne duplikaty (np. z starszych wersji systemu lub Kinga przypadkowo wystawiła 2 FV ręcznie), uruchom audyt. To read-only — wypisze wszystkie pary aktywnych FV tego samego klienta z przecinającymi orderIds w konsoli (F12). Nic nie zapisuje.
🧹 Naprawa danych — Orphan proformy (sieroty po usuniętych zamówieniach)
Co to robi: przed v261 funkcja
Identyfikacja sierot:
Naprawa: proforma →
OD v261 nowy bug nie powstaje —
deleteOrderHard NIE usuwała powiązanych proform. Skutek: po trwałym usunięciu zamówienia jego proforma wisiała w bazie jako unpaid — klient widział ją jako zaległość mimo że zamówienia już nie ma.Identyfikacja sierot:
- Proforma (
typezaczyna się odproforma) zstatus: 'unpaid' orderIdwskazuje na nieistniejące zamówienie LUBorderIdwskazuje na zamówienie zstatus: 'Anulowane'
Naprawa: proforma →
status: 'cancelled' z reason "Backfill v261 — zamówienie nie istnieje / anulowane". Log w payments_audit.OD v261 nowy bug nie powstaje —
deleteOrderHard teraz automatycznie anuluje powiązane proformy.
🔗 Naprawa danych — Proformy zastąpione przez FV (sync proforma↔FV)
Co to robi: historyczny problem do v261: gdy Kinga wystawiała FV do zamówienia z istniejącą proformą, proforma zostawała unpaid mimo że to księgowo to samo. Klient widział 2 dokumenty do zapłaty, choć to jedna kwota. Limit kredytowy źle liczony.
Logika:
OD v262 nowy bug nie powstaje — przy każdym wystawieniu FV (Kinga + admin) proformy są automatycznie zamykane.
Plus przy płatności gotówkowej przy dostawie (CF) — analogicznie.
Logika:
- Proforma
unpaid+ istnieje FV dla tego samego zamówienia → zamknij proformę - Jeśli FV jest
paid→ proforma teżpaid(pokryta przez FV, fv-coverage) - Jeśli FV jest
unpaid→ proformasuperseded(zastąpiona, klient ma teraz płacić FV)
OD v262 nowy bug nie powstaje — przy każdym wystawieniu FV (Kinga + admin) proformy są automatycznie zamykane.
Plus przy płatności gotówkowej przy dostawie (CF) — analogicznie.
🔧 Uzgodnij FV opłacone gotówką
Naprawia rozjazd: zamówienie opłacone gotówką przy dostawie (
Znajduje FV (status
OD v295 nowy bug nie powstaje — przy wystawianiu FV dla zamówienia z już pobraną gotówką FV od razu jest
cashPaymentRegistered), ale FV wystawiona później wisi jako unpaid/przeterminowana.Znajduje FV (status
unpaid, nie anulowane), których wszystkie powiązane zamówienia mają zarejestrowaną gotówkę, i oznacza je jako paid (payment source=cash-on-delivery-coverage) + log w payments_audit.OD v295 nowy bug nie powstaje — przy wystawianiu FV dla zamówienia z już pobraną gotówką FV od razu jest
paid.
Informacje o systemie
Projekt: crm-foodoro-v2
Region: europe-west3
Wersja aplikacji: 2.0