ESO9 Reporting Web Server
Webová verze Reporting Serveru, tj. tisk sestav je volatelný přes URL. Technicky řešeno jako ASP.NET Core API v C# a .NET 10. Načítá offline definici sestavy přímo z databáze ESO9, spouští její datové zdroje, renderuje Stimulsoft předlohu a:
- vrací PDF přímo jako HTTP odpověď, nebo
- uloží PDF do dokumentové databáze a založí dokument i vazbu v DMS ESO9.
Projekt nevolá původní Reporting Server, nelinkuje jeho VB zdroje a nepoužívá jeho binární knihovny. Stimulsoft engine je přímá NuGet závislost.
Konfigurace
Pro lokální spuštění nastavte v appsettings.json nebo přes proměnné:
Eso9__ApplicationConnectionString
Eso9__MaxConcurrentReports
Stimulsoft__LicenseKey
ApiSecurity__ApiKey
Význam konfiguračních hodnot:
Stimulsoft__LicenseKey(Stimulsoft:LicenseKey) je licenční klíč pro Stimulsoft Reports. Je povinný pro korektní renderování sestav a získá se z licence Stimulsoft.ApiSecurity__ApiKey(ApiSecurity:ApiKey) je sdílený klíč pro zabezpečení HTTP API. Pokud je nastaven, musí klient posílat stejnou hodnotu v hlavičceX-Api-Keyu každého požadavku včetněGET /health. Pokud nastaven není, API není chráněno API klíčem.Eso9__MaxConcurrentReports(Eso9:MaxConcurrentReports) určuje maximální počet sestav zpracovávaných současně v jedné instanci aplikace. Platí společně pro endpointy/api/reports/pdfa/api/reports/dms. Pokud jsou všechny dostupné sloty obsazené, další požadavky čekají na jejich uvolnění. Hodnota1znamená sériové zpracování jedné sestavy.
Connection string musí být ve formátu Microsoft.Data.SqlClient, například:
Server=sql01;Database=ESO9START;User ID=report_api;Password=...;Encrypt=True;TrustServerCertificate=True
Připojení k dokumentové databázi se odvodí automaticky ze stejného connection
stringu přidáním _DOC k názvu aplikační databáze. Pro ESO9START se tedy
použije ESO9START_DOC; server, přihlašovací údaje a ostatní parametry zůstanou
beze změny. Položka Database nebo Initial Catalog je proto povinná.
Integrované Windows přihlášení není vhodné pro běžný Linux kontejner.
Volání API
Základní URL služby při lokálním spuštění:
http://server
Pokud je v konfiguraci nastaven ApiSecurity:ApiKey, musí být u každého
požadavku uvedena hlavička X-Api-Key.
Přehled endpointů
| Metoda | URL | Popis |
|---|---|---|
GET | /health | Kontrola dostupnosti služby |
POST | /api/reports/pdf | Vygeneruje PDF a vrátí ho přímo v HTTP odpovědi |
POST | /api/reports/dms | Vygeneruje PDF, uloží ho do DMS ESO9 a vrátí informace o dokumentu |
Tělo požadavku
Endpointy /api/reports/pdf a /api/reports/dms přijímají JSON tělo
ve stejném formátu:
{
"offlineDefinitionId": 3,
"parameters": {
"IDHDOK": 36925,
"PRN_LANG": "CZ"
}
}
Hodnota offlineDefinitionId určuje offline definici sestavy v ESO9.
Objekt parameters obsahuje parametry předané sestavě.
Kontrola dostupnosti služby
GET http://server/health
Příklad pomocí PowerShellu:
Invoke-WebRequest `
-Uri "http://server/health" `
-Method Get
PDF jako odpověď
POST http://server/api/reports/pdf
Content-Type: application/json
X-Api-Key: ...
{
"offlineDefinitionId": 3,
"parameters": {
"IDHDOK": 36925,
"PRN_LANG": "CZ"
}
}
Výsledek má Content-Type: application/pdf a PDF v těle odpovědi.
curl --fail-with-body \
-X POST http://server/api/reports/pdf \
-H "Content-Type: application/json" \
-H "X-Api-Key: $REPORTING_API_KEY" \
-d '{"offlineDefinitionId":3,"parameters":{"IDHDOK":36925,"PRN_LANG":"CZ"}}' \
--output faktura.pdf
Úspěšná odpověď má Content-Type: application/pdf a její tělo obsahuje
vygenerovaný PDF soubor.
Uložení do DMS
POST http://server/api/reports/dms
Content-Type: application/json
X-Api-Key: ...
Tělo požadavku je stejné jako pro endpoint /api/reports/pdf:
{
"offlineDefinitionId": 3,
"parameters": {
"IDHDOK": 36925,
"PRN_LANG": "CZ"
}
}
Příklad pomocí curl:
curl --fail-with-body \
-X POST http://server/api/reports/dms \
-H "Content-Type: application/json" \
-H "X-Api-Key: $REPORTING_API_KEY" \
-d '{"offlineDefinitionId":3,"parameters":{"IDHDOK":36925,"PRN_LANG":"CZ"}}'
Vazba DMS se vezme z IDTABLE, TABLENAME,
IDTYPDOC a IDUZIVATEL vybrané offline definice. Výrazy jako %IDHDOK%
se doplní z prvního řádku dat, UP parametrů nebo parametrů požadavku.
Úspěšná odpověď obsahuje JSON s informacemi o uloženém dokumentu, například:
{
"reportCode": "FAKTURA",
"offlineDefinitionId": 123,
"documentId": 98765,
"fileGuid": "30ad41aa-3180-44c6-8aac-49cbbfd70822",
"fileName": "FAKTURA.pdf"
}
Pokud není nastaven ApiSecurity:ApiKey, hlavička X-Api-Key není povinná.
Příklad volání z SQL databáze
/*
Odeslání dokladu do Web RS
*/
DECLARE @IDHDOK int
DECLARE @headers nvarchar(4000) =
N'<Headers><Accept>*/*</Accept><X-Api-Key>123456</X-Api-Key><Content-Type>application/json</Content-Type></Headers>';
DECLARE @Data nvarchar(max) =
CONCAT(
N'{',
N'"offlineDefinitionId":3,',
N'"parameters":{',
N'"IDHDOK":', CONVERT(nvarchar(20), @IDHDOK), N',',
N'"PRN_LANG":"CZ"',
N'}}'
);
DECLARE @Response nvarchar(max);
SET @IDHDOK = 36925; -- ID dokladu, který chcete vytisknout
EXEC [dbo].[DownloadURL]
'http://10.20.30.36:5099/api/reports/dms',
'POST',
@headers,
@Data,
@Response OUT;
SELECT @Response AS Response;
Žurnál tisku
Každý úspěšně vyrenderovaný tisk do PDF i DMS se zapisuje do HISSTIOFFLINE.
U DMS obsahuje žurnál SESTAVAGUID i FILENAME; u PDF je SESTAVAGUID prázdný
a FILENAME obsahuje název vráceného PDF souboru.
Zpracování parametrů
Hodnoty se skládají v pořadí:
- výchozí hodnoty
QGSPARAM, - hodnoty offline definice
STIOFFLINE_PAR, - hodnoty z HTTP požadavku.
Parametr PRN_LANG z HTTP požadavku má tedy přednost před hodnotou offline
definice i před uživatelským parametrem LEGISLATIVA. Hodnota se zapíše také
do UP_params.PRN_LANG a před renderováním se podle ní použijí překlady uložené
ve GlobalizationStrings Stimulsoft šablony. Pro systémové texty Stimulsoftu
jsou přibaleny lokalizace CZ, DE, EN, HU, IT, PL a SK. Pokud
PRN_LANG není zadán, použije se LEGISLATIVA, případně CZ.
Placeholdery %PARAM% v ROOTVIEWSQL jsou převáděny na SqlParameter.
Fungují původní zápisy %PARAM% i '%PARAM%'; HTTP hodnota se nevkládá
přímo jako SQL text. Chybějící parametr vede k HTTP 400.
Datové zdroje typu akce (VLTYPDZSESTAVY=1) se provedou před renderem.
Sloupce obsahující FILEGUID, firemní logo a razítko se načtou z ESO9DOC.
Sestavení
dotnet restore
dotnet build --configuration Release
dotnet run
Docker
Čisté sestavení Docker image bez použití cache:
docker build --no-cache -t eso9-reporting-web-server-net10:latest .
Uložení sestavené image do TAR souboru pro přenos na jiný Docker nebo Portainer server:
docker save -o eso9-reporting-web-server-net10-latest.tar eso9-reporting-web-server-net10:latest
Na cílovém serveru lze image načíst příkazem:
docker load -i eso9-reporting-web-server-net10-latest.tar
Po načtení bude image dostupná pod názvem
eso9-reporting-web-server-net10:latest.
Vytvořte .env mimo verzování:
ESO9_APPLICATION_CONNECTION_STRING=Server=...;Database=...;User ID=...;Password=...
STIMULSOFT_LICENSE_KEY=...
REPORTING_API_KEY=...
Potom:
docker compose up -d
API bude dostupné na http://localhost:5099.
Kontejner obsahuje základní DejaVu fonty a vlastní TTF fonty ze složky Fonts.
Vlastní fonty se při startu registrují také přímo do StiFontCollection a při
exportu PDF se explicitně vkládají do výsledného dokumentu. Po přidání nebo
změně TTF souborů je nutné aplikaci znovu sestavit a vytvořit novou Docker image.
Diagnostika chyb a traceId
Klient při chybě dostane standardní ProblemDetails odpověď s bezpečnou zprávou
a položkou traceId. Stejná hodnota je uvedena v hranatých závorkách u všech
logů daného požadavku. Neočekávaná chyba je v logu zapsána včetně úplného stack
trace a vnitřních výjimek.
Logy se zapisují současně na konzoli a do rotujících souborů:
logs/eso9-reporting-YYYYMMDD.log
Soubor se rotuje denně nebo po 50 MB a uchovává se nejvýše 30 souborů. Cestu a
ostatní parametry lze změnit standardním přepsáním sekce Serilog konfigurace.
Lokální dohledání v PowerShellu:
Select-String -Path .\logs\eso9-reporting-*.log -Pattern '0HNNE6AAQS2NB:00000003' -Context 0,30
Dohledání v Docker Compose:
docker compose exec eso9-reporting-web-server \
grep -n -A 30 '0HNNE6AAQS2NB:00000003' /app/logs/eso9-reporting-*.log
Compose používá persistentní volume report-logs, takže soubory přežijí restart
nebo nahrazení kontejneru. Protože obsahují podrobné technické chyby, musí mít
přístup k volume pouze administrátoři služby.
DMS konzistence
PDF, záznam dokumentu a jeho vazbu na tabulku ESO9 zakládá stored procedura
spDokument_Zalozeni. Volání procedury a zápis žurnálu HISSTIOFFLINE proběhnou
v jedné transakci aplikační databáze. API vrací idDokument z výstupního parametru
procedury a fileGuid načtený ze založeného záznamu DOKUMENT.