Wiki
Pipeline generowania PDF
Jak QuoteNode generuje brandowane dokumenty PDF ze snapshotów ofert przy użyciu Thymeleaf i Gotenberg.
Pipeline generowania PDF
QuoteNode generuje gotowe do druku dokumenty PDF z danych oferty w pipeline dwustopniowym: najpierw render HTML przez Thymeleaf, potem konwersja do PDF przez Gotenberg.
Przegląd pipeline’u
Snapshot oferty (JSON)
│
▼
Silnik szablonów Thymeleaf
├── fragmenty layoutu (header, tabela pozycji, sumy, footer)
├── CSS inline dla zgodności z Gotenberg
├── obrazy produktów osadzone jako base64 URI
└── wsparcie paginacji (Page X/Y)
│
▼
Dokument HTML (kompletny i samowystarczalny)
│
▼
Gotenberg (kontener oparty o Chromium)
│
▼
Plik PDF (zapisany z sumą kontrolną SHA-256)
Renderowanie oparte o snapshoty
PDF-y są zawsze renderowane z niemutowalnych snapshotów, a nie z live data. Gdy oferta zostaje wysłana:
- system przechwytuje kompletny JSON snapshot stanu oferty,
- snapshot obejmuje dane klienta, pozycje, ceny, kursy FX, branding i ustawienia szablonu,
- snapshot jest przechowywany i wersjonowany.
Dzięki temu PDF zawsze odpowiada dokładnie temu, co zostało zaoferowane w danym dniu, niezależnie od późniejszych zmian w katalogu, danych klienta czy brandingu.
System szablonów
Rodziny szablonów
Aktualna implementacja zawiera rodzinę CLASSIC_B2B_TECHNICAL. Kolejne warianty są planowane, na przykład:
MINIMAL_B2B,B2C_FRIENDLY,MULTI_CURRENCY,SERVICE_HOURS.
Struktura szablonu
Każdy szablon PDF składa się z:
- Headera — logo sprzedawcy, nazwy firmy, adresu i danych kontaktowych
- Sekcji meta — danych odbiorcy, numeru oferty, handlowca, daty i okresu ważności
- Tabeli pozycji — z konfigurowalnymi kolumnami cenowymi
- Podsumowania — subtotal, rabaty, dostawa, VAT i suma końcowa
- Warunków handlowych — płatność, gwarancja, dostawa, transport
- Sekcji podpisu — przestrzeń na akceptację
- Stopki — dane rejestrowe firmy
Konfigurowalne kolumny
Kolumny tabeli pozycji są kontrolowane per oferta:
| Ustawienie | Efekt |
|---|---|
showSku | Pokazuje lub ukrywa kolumnę SKU |
showImages | Wyświetla zdjęcia produktów w tabeli |
imageSize | Mały rozmiar, średni albo brak |
showDescription | Dołącza opisy produktów |
showUnit | Pokazuje jednostkę miary |
showVatColumn | Pokazuje kolumnę VAT |
priceMode | NET, GROSS albo pełne NET+VAT+GROSS |
discountDisplay | BAKED_IN, SHOW_COLUMN albo HIDDEN |
Integracja z brandingiem
PDF automatycznie używa brandingu skonfigurowanego dla tenanta:
- Logo w headerze,
- kolor główny dla nagłówków i akcentów,
- kolor dodatkowy dla elementów drugorzędnych,
- dane firmy do stopek i sekcji kontaktowych,
- własny tytuł oferty zamiast domyślnego nagłówka,
- badge “Powered by” w edycji Free.
Tryby przetwarzania
Synchroniczny
Dla ofert z mniej niż 50 pozycjami:
- API uruchamia generowanie PDF,
- Thymeleaf renderuje HTML, a Gotenberg konwertuje go do PDF,
- plik wraca w tej samej odpowiedzi HTTP.
Asynchroniczny
Dla większych ofert lub przy większym obciążeniu:
- API zwraca
202 AcceptedzjobId, - w PostgreSQL zapisywany jest rekord
PdfJob, - worker podejmuje zadanie,
- po sukcesie plik jest zapisywany, status aktualizowany, a użytkownik dostaje powiadomienie,
- po błędzie działa retry z backoffem,
- zadania trwale nieudane trafiają do DLQ.
Przechowywanie i retencja
Wygenerowane PDF-y są przechowywane jako pliki, a ich metadane trafiają do tabeli generated_documents:
- nazwa pliku,
- rozmiar,
- suma SHA-256,
- wersja snapshotu,
- timestamp wygenerowania.
Domyślna retencja wynosi 365 dni. Po tym czasie plik może zostać usunięty, ale rekord metadanych nadal pozostaje do celów audytowych.
Konfiguracja Gotenberg
Gotenberg działa jako osobny kontener w stacku wdrożeniowym. Zapewnia:
- poprawny rendering nowoczesnego CSS,
- paginację i marginesy,
- obsługę rozmiarów stron,
- nagłówki i stopki.
Backend komunikuje się z nim przez HTTP API. Nie ma potrzeby osadzać Chromium bezpośrednio w aplikacji backendowej.