Kompletny przewodnik po module fakturowania w SerwisRun. Dokument opisuje wystawianie faktur w 4 trybach (konserwacja / interwencja / harmonogram umowy / recznie), import faktur zakupu z KSeF, automatyczne tworzenie PZ oraz oznaczanie zrodlowych dokumentow jako zafakturowanych.
Zmiana 2026-03-20: Faktury w menu bocznym to teraz grupa z dwoma pozycjami: Faktury wystawione (/invoices/issued) i Faktury zakupu (/invoices/purchase). Importer KSeF dla faktur zakupu + auto-PZ (wykrywanie nr zamowienia PO z opisu).
| Tabela | Opis |
|---|---|
invoices | Naglowek faktury — numer, data wystawienia, data sprzedazy, termin, kwoty, status, direction (outgoing/incoming) |
invoice_items | Pozycje faktury — nazwa, ilosc, JM, cena netto, VAT, kwota brutto |
contract_invoice_schedules | Harmonogram faktur umowy — stale platnosci wg cyklu (miesiac, kwartal, rok) |
suppliers | Dostawcy — NIP, REGON, adres, termin platnosci, kategorie materialow |
warehouse_documents | Dokumenty PZ powiazane z invoice_id (faktury zakupu) |
Wartosc direction | Opis | Widok |
|---|---|---|
outgoing | Faktury wystawione (sprzedazy) — to, co wysylamy klientowi | /invoices/issued (IssuedInvoicesPage) |
incoming | Faktury zakupu — to, co otrzymujemy od dostawcy | /invoices/purchase (PurchaseInvoicesPage) |
U Uprawnienie: invoices / VIEW + EDIT (wystawianie)
W module /invoices/issued przycisk otwiera kreator faktury (/invoices/issued/wizard) — 3-fazowy wizard z pionowym sidebarem.
| Tryb | Zrodlo | Endpoint | Kiedy stosowac |
|---|---|---|---|
| A. Konserwacja | Niefakturowane konserwacje (status: wykonana/zweryfikowana) | POST /invoices/from-maintenance/:id |
Najczestszy — faktura po kazdej konserwacji |
| B. Interwencja | Niefakturowane protokoly naprawy (repair_protocols.invoiced = false) | POST /invoices/from-repair-protocol/:id |
Naprawy (nie gwarancyjne — is_warranty = false) |
| C. Harmonogram umowy | Niezafakturowane pozycje contract_invoice_schedules |
POST /invoices/from-schedule/:contractId |
Ryczalt / rata kwartalna / miesieczna |
| D. Recznie | Wybor klienta + pusty formularz | POST /invoices |
Korekty, niestandardowe rozliczenia |
Po wyborze zrodla system automatycznie wypelnia (zobacz sekcja „Pre-fill" ponizej):
company_settingsUzytkownik moze skorygowac dowolne pole przed zapisem. System weryfikuje VAT, sumy netto/brutto.
Backend endpoint POST /invoices/from-maintenance/:id robi:
JOIN contracts ON maintenances.contract_id = contracts.idJOIN clientsissueDate + contract.paymentTermDaysAnalogicznie, ale zrodlem jest repair_protocols. Dodatkowo sprawdza is_warranty — jesli true, faktura NIE jest tworzona (gwarancja nie fakturowana).
Dla umow z platnosciami ryczaltowymi (np. 1000 PLN/miesiac). Pozycja harmonogramu: {period: 'month', amount: 1000, dueDate: '2026-04-10', isIssued: false}. Po wystawieniu faktury → isIssued=true, issuedAt.
Brak pre-fill. Uzytkownik wypelnia wszystko od zera — kreator pokazuje tylko walidacje i podpowiedzi (NIP lookup z MF, obliczanie sum).
Po wystawieniu faktury system automatycznie oznacza zrodlo jako zafakturowane, aby zapobiec podwojnemu fakturowaniu:
| Zrodlo | Pole oznaczajace |
|---|---|
| Konserwacja | maintenances.invoice_id (FK), status = 'invoiced' |
| Protokol naprawy | repair_protocols.invoiced = true, invoice_id, invoiced_at |
| Harmonogram umowy | contract_invoice_schedules.is_issued = true, issued_at |
| Kosztorys | cost_estimates.status = 'invoiced' |
| Pozycje WZ | warehouse_document_items.invoice_id, invoiced_quantity |
| Interwencja materialy | intervention_materials.consumption_status = 'invoiced' |
Gwarancja: Jesliis_warranty = truew interwencji, status zmienia sie nawarranty(bez faktury). System nie pozwala utworzyc faktury z interwencji gwarancyjnej.
U Uprawnienie: invoices / EDIT
Moduł /invoices/purchase (PurchaseInvoicesPage) wyswietla faktury z direction = 'incoming'. Dwa zrodla dodawania:
invoices.supplier_id → FK do suppliers. System weryfikuje NIP przez API MF (Biala Lista):
invoices/EDITPOST /invoices/purchase/fetch-ksef (zapytanie do API KSeF z filtrem po dacie)invoices.ksef_uid)POST /invoices/purchase/import-ksef → dla kazdej faktury:
ksef.service.downloadInvoice(uid))parseFaVatXml) — wyciaga naglowek, pozycje, dane dostawcyinvoices z direction=incoming, ksef_uidinvoice_items 1:1 z pozycjami XMLksef_uid (UNIQUE INDEX) zapobiega ponownemu importowi tej samej faktury. Jesli uzytkownik kliknie „Importuj" dwa razy, system pomija juz zaimportowane.
Po zaimportowaniu faktury zakupu system moze automatycznie wygenerowac dokument PZ (przyjecie zewnetrzne) — dzieki temu material od razu trafia na stan magazynu.
POST /invoices/purchase/:id/create-pz — tworzy PZ z nastepujacymi krokami:
materials:
ean (kod kreskowy z pozycji faktury)manufacturer + partNumbermanufacturer + typesupplier.branch_idPO-YYYY-NNNNNN w opisie (powiazanie z parts_orders)warehouse_documents z type=PZ, supplier_invoice_number, supplier_idwarehouse_document_items 1:1 z faktury, z cena zakupumaterial_batches) z:
purchase_date — data dokumentuunit_price — z fakturyremaining_quantity — pelna ilosc z PZsupplier_id, purchase_invoice_id, warehouse_document_idwarehouse_stock.quantity += qty w magazynie docelowymdraft → confirmed| Status | Opis | Kto zmienia |
|---|---|---|
| draft | Robocza — mozna edytowac, brak finalnego numeru | Uzytkownik |
| issued | Wystawiona — finalny numer, zapisana do ewidencji | Uzytkownik (Wystaw) |
| sent | Wyslana do klienta (email) lub do KSeF | System |
| paid | Zaplacona — odebrana platnosc | Uzytkownik (manual) lub import z banku |
| overdue | Przeterminowana — due_date < now() AND status != paid | System (derywowany) |
| cancelled | Anulowana (korekta) — z powiazana faktura korygujaca | Uzytkownik |
Priorytet (najwyzszy → najnizszy):
umowa (contracts.payment_term_days) → klient (clients.payment_days_due) → firma (company_settings.default_payment_term_days) → 14 dni (hardcoded fallback)
Wyliczanie terminu: dueDate = issueDate + termDays.
| Poziom | Gdzie |
|---|---|
| Umowa | Szczegoly umowy → zakladka „Dane podstawowe" → pole „Termin platnosci (dni)" |
| Klient | Szczegoly klienta → zakladka „Rozliczenia" |
| Firma (domyslny) | Panel Administracyjny → Dane firmy → „Domyslny termin platnosci" |
Od 2026-07 KSeF jest obowiazkowy dla duzych podatnikow. System wspiera:
status=issued AND ksef_sent=falseinvoices.ksef_status (pending / accepted / rejected), ksef_uid, ksef_rejection_reasonW module /invoices/issued lista faktur moze byc eksportowana do Excel z kolumnami: numer, data, klient, NIP, kwota netto, VAT, brutto, termin, status. Export respektuje filtry tabeli.
Format JPK_FA (XML) — eksport zgodny z wymaganiami MF dla kontroli skarbowych. Dostepny w Raporty → JPK.