taxmachine.pl

Portal akceptacji e-faktur dla biur rachunkowych

Klient biura rachunkowego loguje się przez przeglądarkę i akceptuje lub wyklucza e-faktury zakupowe z KSeF — zanim biuro je zaksięguje.

Opublikowano

Po co to

W KSeF klient nie ma kontroli nad tym, jakie faktury do niego trafiają — sprzedawca wystawia, system publikuje, biuro ściąga. Część dokumentów to normalne koszty, część to pomyłki: prywatne zakupy wystawione na firmowy NIP, duplikaty, faktury skierowane na wspólnika zamiast na firmę. Bez akceptacji biuro musiałoby księgować wszystko, a potem żmudnie korygować — albo wymieniać z klientem maile w stylu "akceptujesz fakturę X?" / "tak" / "a pozycję 3 z tej drugiej?".

Portal eliminuje ten ping-pong. Biuro pobiera batch e-faktur klienta z KSeF i otwiera miesiąc akceptacji. Klient dostaje maila z linkiem auto-login, w przeglądarce przegląda dokumenty i klika Akceptuj lub Wyklucz — także dla pojedynczych pozycji w fakturze. Decyzje synchronizują się z bazą TaxMachine, a biuro księguje gotową dyspozycję jednym kliknięciem.

Workflow

(1) Biuro pobiera e-faktury klienta z KSeF (klient KSeF w TaxMachine)
        ↓
(2) Biuro otwiera "miesiąc akceptacji" — TaxMachine generuje
    wizualizacje HTML faktur i zapisuje do bazy
        ↓
(3) Biuro uruchamia masową wysyłkę zaproszeń — outbox kolejkuje
    maile, worker wysyła z SMTP biura
        ↓
(4) Klient klika link auto-login → /auto-login?token=...
        ↓
(5) Klient widzi listę miesięcy, wchodzi w batch, widzi listę faktur
        ↓
(6) Klient akceptuje / wyklucza dokument lub pojedyncze pozycje
        ↓
(7) Klient klika "Zamknij miesiąc" — decyzje wracają do TaxMachine
        ↓
(8) Biuro w TaxMachine księguje faktury zgodnie z dyspozycją

Co widzi klient w portalu

Auto-login z maila. Link w mailu prowadzi pod /auto-login?token=.... Token zawiera identyfikator użytkownika, datę ważności i podpis HMAC-SHA256 — generowany identycznym algorytmem po stronie portalu i TaxMachine. Domyślna ważność linku — 168 h (7 dni; konfigurowalne przez InvitationLinkLifetimeHours). Alternatywnie klient loguje się hasłem na /Account/Login (tym samym, którego używa w głównym TaxMachine).

Lista miesięcy do akceptacji (/Approvals). Klient z trzema firmami widzi trzy oddzielne batche na miesiąc. W każdym wierszu: firma, rok/miesiąc, status (open, submitted_by_client, accepted_by_office, closed, reopened), liczba dokumentów, ile pozostało do decyzji, ewentualny deadline. Na górze sekcja Wymaga uwagi — batche z dokumentami w stanie pending lub partial.

Szczegół batcha (/Approvals/Batch/{id}). Lista faktur miesiąca: numer, kontrahent, kwoty, status. Akceptacja lub wykluczenie wprost z listy, edytowalny komentarz do batcha, historia powiadomień (kiedy poszło zaproszenie, kiedy przypomnienie, czy dotarło).

Szczegół dokumentu (/Approvals/Document/{id}). Po lewej — metadane; po prawej — pełna wizualizacja HTML, taka sama jak widzi księgowy w TaxMachine. Wizualizacja jest renderowana po stronie programu Delphi, gzip-skompresowana i zapisywana do bazy. Portal tylko dekompresuje i wyświetla — bez ryzyka rozjazdu między widokiem klienta a widokiem biura. Niżej tabela pozycji z przełącznikiem wyklucz/przywróć i komentarzem. Główne przyciski: Akceptuj dokument, Wyklucz dokument, Zapisz komentarz.

Decyzje per pozycja. Przykład: trzy pozycje, jedna to prywatny krem, dwie to tonery do biura. Klient wyklucza pozycję nr 2, dokument przechodzi w stan partial, TaxMachine zaksięguje tylko pozostałe linie. Kliknięcie Akceptuj dokument nie przywraca wcześniej wykluczonych pozycji — trzeba je przywrócić ręcznie.

Read-only po zamknięciu. W stanach submitted_by_client, accepted_by_office, closed oraz po upływie deadline-u portal blokuje edycję — zarówno w interfejsie, jak i po stronie serwerowej, niezależnie od tego, czy worker zdążył zamknąć batch.

Automatyczne zamknięcie po deadline. Worker w tle dla batchy open/reopened po upływie deadline-u traktuje wszystkie dokumenty pending jako zaakceptowane i zamyka miesiąc. Polityka "milcząca zgoda" — klient ma X dni na zgłoszenie zastrzeżeń, inaczej księgujemy całość.

Co robi biuro w TaxMachine

Otwarcie batcha. Z UI Delphi albo komendą CLI --command prepare-approvals --year YYYY --month M. Dla każdego aktywnego klienta z e-fakturami w miesiącu TaxMachine tworzy rekord akceptacji miesiąca wraz z rekordami akceptacji dokumentów i pozycji, renderuje wizualizacje HTML i ustawia batch w stanie open. Opcjonalnie --approval-deadline YYYY-MM-DD ustawia termin milczącej zgody.

Masowa wysyłka. /Approvals/Bulk albo CLI --command queue-invitations/queue-reminders. Preview w gridzie pokazuje firmę, biuro, liczbę e-faktur, status batcha (new/existing-editable/existing-locked/missing) i flagi problemów (brak biura, brak odbiorcy, brak SMTP). Eksport do CSV przed wysłaniem. Przypomnienia tylko dla batchy open/reopened.

Monitoring. Widok batcha pokazuje historię powiadomień (queued/sent/failed/cancelled) z liczbą prób. Failed można ręcznie ponowić.

Integracja z księgowaniem. Po zamknięciu miesiąca przez klienta lub po auto-close portal zapisuje na rekordzie e-faktury: listę pozycji wyłączonych z księgowania, sumę do księgowania (netto dla VAT/OSS, brutto w pozostałych), znacznik zatwierdzenia księgowania, datę zatwierdzenia oraz uwagi klienta. Biuro w TaxMachine ma gotową decyzję — księguje jednym kliknięciem.

Reopen. Jeśli klient pominął coś istotnego, biuro cofa zamknięcie (submitted_by_client/accepted_by_officereopened). Batch closed nie podlega reopenowi — korekty robi się normalnym wpisem księgowym.

API + integracje

Backend Delphi wystawia REST API. Główne endpointy:

  • GET /client/ksef-approvals/firma/{firmaId} — lista batchy
  • POST /client/ksef-approvals/open — otwarcie/pobranie batcha dla (firmaId, rok, miesiąc)
  • GET /client/ksef-approvals/batch/{batchId} — szczegóły
  • GET /client/ksef-approvals/document/{id} — pozycje i sumy
  • POST /client/ksef-approvals/document/{id}/accept — akceptacja dokumentu
  • POST /client/ksef-approvals/document/{id}/exclude — wykluczenie dokumentu (z komentarzem)
  • POST /client/ksef-approvals/document/{id}/line/{nrPozycji} — decyzja per pozycja: {"decision": "excluded", "comment": "..."}
  • POST /client/ksef-approvals/batch/{batchId}/submit — zatwierdzenie miesiąca

Backend Delphi i portal webowy korzystają z tej samej bazy MySQL/MariaDB.

Komendy CLI

Portal ma tryb konsolowy do automatyzacji (cron):

KomendaKiedy używać
--command prepare-approvals --year Y --month M [--approval-deadline D]Otwarcie batchy dla miesiąca po imporcie e-faktur z KSeF
--command queue-invitations --year Y --month MWysłanie zaproszeń do klientów z otwartymi batchami
--command queue-reminders --year Y --month MPrzypomnienia dla batchy wciąż open / reopened
--command process-expired-auto-approvalsWymuszone sprawdzenie deadline-ów (one-shot zamiast workera w tle)

Dodatkowe przełączniki: --office-id N (filtr po biurze), oraz parametry bazy (--db-server, --db-port, --db-name, --db-user, --db-password, --db-sqlite-file), portu (--urls) i HTTPS-redirectu (--db-https-redirect).

Po stronie Delphi te same operacje uruchamiane są z UI TaxMachine — startując CLI portalu jako proces zewnętrzny. Typowy harmonogram: prepare-approvals 1-go każdego miesiąca z deadlinem na 10-tego, queue-invitations 2-go, queue-reminders 7-go.

Notyfikacje

Każdy mail jest wierszem w outboksie powiadomień, wysyłanym asynchronicznie przez worker w tle (domyślnie co 10 s). Próby są logowane, a w razie błędu worker retryuje zgodnie z konfiguracją (limit prób i opóźnienie między próbami).

Nadawcą jest biuro rachunkowe, nie portal. SMTP pobierany jest z konfiguracji biura rachunkowego klienta. Fallback — globalny SMTP serwera webowego. Adresatem jest zawsze aktywny użytkownik klienta — biura rachunkowe nie dostają tych maili.

Typy: invitation (pierwsza informacja) i reminder (przypomnienie dla batchy open/reopened). W widoku batcha biuro może ręcznie ponowić każdy failed/cancelled rekord, jeśli typ powiadomienia jest nadal dozwolony dla bieżącego statusu batcha.

Wymagania techniczne

Backend Delphi. Serwer HTTP hostuje kontroler akceptacji (domyślny port 8080).

Portal webowy. Razor Pages + htmx, .NET SDK 10, dostęp do bazy MySQL/MariaDB (ta sama instancja co główny TaxMachine). Konfiguracja w appsettings.json.

Baza danych. Tabele akceptacji e-faktur w głównej bazie TaxMachine — schemat zarządzany po stronie programu Delphi. W dev opcjonalnie SQLite.

Hosting. PublicBaseUrl to publiczny adres portalu wstawiany w linki auto-login. Portal może być hostowany przez biuro (np. pod subdomenę) albo udostępniony przez dostawcę TaxMachine.

Dostęp do firm. Portal weryfikuje uprawnienia użytkownika i jego role (Admin/PowerUser/Manager/Owner). Zwykły klient widzi tylko swoje firmy.

Bezpieczeństwo

Auto-login token. Podpis HMAC-SHA256 z sekretem identycznym po stronie programu Delphi i portalu webowego, bez szyfrowania — każdy, kto zna sekret i ma identyfikator użytkownika, może wygenerować ważny token. Walidator linków logowania odrzuca tokeny z błędnym podpisem lub po terminie ważności. Sekret jest obecnie zaszyty w kodzie; przed wdrożeniem produkcyjnym zaleca się wyciągnięcie do konfiguracji i rotację.

HTTPS. Konfigurowalny redirect HTTPS. Produkcyjnie portal powinien stać za reverse proxy z certyfikatem TLS.

Kontrola dostępu — portal sprawdza na każdym żądaniu, czy zalogowany użytkownik ma dostęp do firmy z batcha. Globalny handler błędów blokuje swap dla odpowiedzi 400+ i pokazuje alert.

Niemutowalność KSeF. XML faktury w KSeF nigdy nie jest modyfikowany. Decyzje klienta to overlay księgowy w tabelach akceptacji; do rekordu e-faktury synchronizowane są tylko pola wynikowe potrzebne do księgowania.

Status wdrożenia

Portal istnieje w dwóch równoległych implementacjach UI:

Portal Razor Pages + htmx — działa. Pełny pionowy slice: otwieranie batchy, lista, widok batcha, widok dokumentu z podglądem HTML, decyzje per dokument i per pozycja, sekcja księgowania, wysyłka zaproszeń i przypomnień (pojedyncza i masowa), monitoring outboksu, auto-close po deadline. Testy integracyjne pokrywają flow od otwarcia batcha przez akceptację, wykluczenie pozycji, zatwierdzenie miesiąca, po blokadę edycji.

Portal Blazor Web App + DevExpress v25.2.6 — w trakcie. Nowa implementacja od zera, spójność z resztą platformy webowej TaxMachine. Aktualnie zakończony Milestone 1: szkielet uruchamia się, workery startują, podstawowa nawigacja (sidebar, topbar), tryb CLI. Roadmapa: M2 — auth end-to-end, M3 — lista batchy z gridem, M4 — szczegół batcha, M4.5 — prerender HTML w Delphi, M5 — szczegół dokumentu, M6 — masowa wysyłka, M7 — utwardzenie i deploy. Po osiągnięciu parity stary portal zostanie wygaszony.

Czego jeszcze nie ma w żadnej wersji. UI biura w portalu do przejść submitted_by_clientaccepted_by_officeclosed / reopened (obecnie tylko w Delphi); audyt zmian ("kto, kiedy, z jakiego IP"); 2FA i polityka silnych haseł; lokalizacja inna niż polska; załączniki do decyzji.

Powiązane