Tisky a exporty prostřednictvím Web API ABRA Gen
Kapitola popisuje možnosti generování tiskových sestav, exportů a B2B exportů prostřednictvím zasílání HTTP požadavků v rámci Web API.
V kapitole Knihovna praktických příkladů Web API naleznete konkrétní příklad, jak prostřednictvím rozhraní Web API realizovat vygenerování tiskové sestavy objednávky přijaté a její uložení do PDF souboru. Možnosti Web API jsou však širší.
Základní principy:
- jsou podporovány standardní tisky, definovatelné exporty a B2B exporty
- nejsou podporovány Reporty prodeje a podobné agendy
- tisky i exporty je možné používat v rámci základního (GET) i rozšířeného (POST) dotazování
- tisknout i exportovat je možné do formátů PDF, XLSX a CSV
- tisknout lze i jednotlivé revize záznamů, Pro tisk revizí platí, že daný typ dokladů revize podporuje a že jsou povolené v agendě Firemní údaje, kategorie Obecná nastavení, položka Povolit revize dat
- formát se definuje prostřednictvím Content negotiation (HTTP hlavička Accept) nebo přímo v URL požadavku doplněním odpovídající přípony k názvu kolekce (pouze v základním dotazování)
- součástí zasílaného požadavku je ID tiskové sestavy, exportu nebo B2B exportu a seznam ID záznamů, které se mají vytisknout nebo vyexportovat
- k určení typu výstupu (tisk, definovatelný export nebo B2B export) slouží speciální query parametry
V tiskových sestavách je vždy zapotřebí nějakým způsobem specifikovat ID tištěného záznamu (nebo skupiny záznamů), ID tiskové sestavy a požadovaný výstupní formát.
Dostupné možnosti si ukážeme na příkladech.
HTTP požadavek (základní dotazování):
GET http://localhost:699/demodata/issuedinvoices/8M00000101?select=id&report=W400000001
- demodata = alias spojení
- issuedinvoices = název kolekce (Faktury vydané)
- 8M00000101 = ID tištěného záznamu (konkrétní faktury vydané)
- W400000001 = ID použité tiskové sestavy (Formulář faktury vydané)
Pokud bychom serveru poslali uvedený požadavek bez dalšího upřesnění, nevytvořila by se žádná sestava, ale obdrželi bychom zpátky pouze ID záznamu (viz použití klauzule SELECT) ve formátu JSON. Přestože je specifikováno ID reportu, není určen formát. Query parametr report se v takovém případě ignoruje a požadavek je zpracován jako zcela běžný požadavek na získání dat.
Výsledek zpracování:
{"id":"8M00000101"}
Formát můžeme určit dvěma způsoby:
- buď společně s požadavkem provést Content negotiation (odeslat HTTP hlavičku Accept)
- nebo formát zahrnout přímo do URL požadavku jako "příponu" názvu kolekce
Obě metody podporují trojici formátů - PDF, XLSX a CSV.
Společně s požadavkem odešleme HTTP hlavičku Accept, ve které v závislosti na požadovaném výstupním formátu uvedeme jeden ze tří dostupných typů:
Accept: application/pdf
Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Accept: text/csv
Místo odesílání HTTP hlavičky je možné formát specifikovat přímo v URL požadavku, který bychom pro jednotlivé formáty upravili následovně:
GET http://localhost:699/demodata/issuedinvoices/8M00000101.pdf?select=id&report=W400000001
GET http://localhost:699/demodata/issuedinvoices/8M00000101.xlsx?select=id&report=W400000001
GET http://localhost:699/demodata/issuedinvoices/8M00000101.csv?select=id&report=W400000001
Není-li uvedeno jinak, v příkladech v této kapitole předpokládáme používání Content negotiation, proto URL adresy specifikaci formátu neobsahují. Některý ze způsobů stanovení výstupního formátu je nicméně zapotřebí používat.
Pokud je v rámci Content negotiation požadován určitý formát a v URL požadavku je uveden jiný, formát specifikovaný v URL má přednost před hlavičkou, tj.
Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
...
GET http://localhost:699/demodata/issuedinvoices/8M00000101.pdf?select=id&report=W400000001
způsobí vygenerování tiskové sestavy ve formátu PDF (hlavička s požadavkem na XLSX se ignoruje).
Používat klauzuli SELECT není povinné (pouze obecně doporučené, získávání celých objektů včetně nepotřebných polí je neefektivní). Je však nutné zajistit, aby odpověď vždy obsahovala pole s názvem ID, které slouží k výběru objektů pro tisk. Takže zatímco požadavek ve tvaru
GET http://localhost:699/demodata/issuedinvoices/8M00000101?report=W400000001
tiskový výstup vytvoří, následující požadavek skončí chybou (400 Bad Request):
GET http://localhost:699/demodata/issuedinvoices/8M00000101?select=displayname&report=W400000001
{"title":" Chybějící field \"ID\"","description":" V dotazu chybí field \"ID\", kterým jsou vybírány BO k exportu"}
Stejnou chybou by požadavek skončil, kdybychom sice vybrali ID, ale přejmenovali ho prostřednictvím aliasu:
GET http://localhost:699/demodata/issuedinvoices/8M00000101?select=id+as+IDnumber&report=W400000001
{"title":" Chybějící field \"ID\"","description":" V dotazu chybí field \"ID\", kterým jsou vybírány BO k exportu"}
Uvedený příklad je jednou z možností, jak může požadavek vypadat. Ke stejnému výsledku nicméně povedou také následující varianty:
Základní dotazování nad kolekcí, s klauzulí WHERE:
GET http://localhost:699/demodata/issuedinvoices?select=id&where=id+eq+'8M00000101'&report=W400000001
Rozšířené dotazování nad subresourcem kolekce BO:
POST http://localhost:699/demodata/issuedinvoices/query?report=W400000001
Tělo požadavku:
{
"select": "id",
"where": "id='8M00000101'"
}
Rozšířené dotazování nad obecným resourcem:
POST http://localhost:699/demodata/query?report=W400000001
Tělo požadavku:
{
"class": "issuedinvoices",
"select": "id",
"where": "id='8M00000101'"
}
Při používání rozšířeného dotazování je nutné požadovaný výstupní formát specifikovat v HTTP hlavičce, obdoba varianty "s příponou" ze základního dotazování zde k dispozici není.
Níže uvedená chyba znamená, že URL požadavku neobsahuje query parametr report (ani export, viz Generování definovatelných exportů a B2B exportů), přestože:
- v URL požadavku je formou přípony k názvu kolekce specifikován některý z podporovaných výstupních formátů (PDF, XLSX, CSV)
-
nebo byl požadavek odeslán s hlavičkou Accept, ve které byl specifikován některý z podporovaných výstupních formátů
- application/pdf
- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- text/csv
{
"title": " Chybějící parametry",
"description": " Není zadán parametr \"report\" ani \"export\""
}
Některé tiskové sestavy ve vizuálním prostředí ABRA Gen vyžadují zadání hodnot uživateli před samotným tiskem. V rámci API je toto řešeno nepovinným parametrem dialoginputs typu pole.
Obecné fungování
Systém umí pracovat s QR funkcemi: NxMessageBox, NxInputDialog, NxDateInputDialog, NxChoiceInputDialog, NxTextInputDialog, NxMultiInput.
Když se parametr zadá, tak v případě vstupu přes některou z výše uvedených funkcí se tento vstup vytáhne z pole dialoginputs. V případě, že je hodnota potřeba a pole dialoginputs je prázdné, vyvolá se specifická výjimka s popisem volání funkce včetně aktuálních parametrů, popisem funkce a příkladem. Návratový kód volání je v tomto případě 422. Na základě těchto informací se do pole dialoginputs doplní další hodnota a provede se nové kolo volání. Jakmile se pokryjí všechny dialogy, sestava(nebo export) se vytiskne.
Jako hodnotu do pole dialoginputs lze použít i null hodnotu. V takovém případě se namísto null použije výchozí hodnota pro danou funkci a dané volání. Práce s defaultní hodnotu se poměrně liší v závislosti na funkci. Proto je třeba si prostudovat popis volané QR funkce.
Pokud se použije nějaký chytrý klient, lze tyto dialogy postupně zobrazovat uživateli a posílat do systému. V případě nevizuálního klienta, anebo pokud je to někde pevná volba se vyřeší pole dialoginputs pro konkrétní případ, a pak se používá. Při změně tiskové sestavy je nutné tyto hodnoty doopravit.
Postup je jednoduchý - začne se s prázdným polem dialoginputs a postupně se podle vrácených chybových odpovědí doplňují další hodnoty.
Výjimka QR funkce NxMultiInput
U všech dialogů kromě NxMultiInput se jedná o jednoduché hodnoty, většinou typu text nebo číslo. Dialog NxMultiInput umožňuje zadávat více voleb současně (je to takový adhoc formulář). V jednom z jeho parametrů je struktura formuláře v interním string formátu ABRA Gen. Výjimka pro tuto funkci navíc obsahuje pole definition, kde je tato struktura přeložena do JSON objektové struktury.
Tento dialog očekává v poli dialoginputs hodnotu typu objekt. Je ve formátu slovníku - klíče odpovídají hodnotě položky name z definition a hodnoty se převezmou do sestavy, jako by byly zadány v dialogu. Více ukáže konkrétní příklad.
JSON v odpovědích je zformátovaný kvůli čitelnosti, takže v něm můžou být z hlediska JSON formátu syntaktické chyby.
Tisk bez pole dialoginputs proběhne standardním způsobem
POST http://localhost:80/demo/dynsql/0QSD0SGZDTX411PSLWCG3LUGYK/exec?report=N310000001
{
"select": ["Cnt"],
"where": [
{"id": "Year", "value": "2026"},
{"id": "Code", "value": "1"}
]
}
V tomto případě vrací chybu:
status code: 400
response headers:
==============
Date : Thu, 12 Feb 2026 09:49:44 GMT
Content-Type : application/json
Content-Length : 314
Server : Jetty(11.0.24)
response body:
==============
{
"title": "Chyba při zpracování api dotazu",
"description": "Tisk obsahuje chyby nebo chráněné položky a není možné v něm pokračovat (chyba: Export obsahuje chyby nebo chráněné položky a není možné v něm pokračovat (chyba: ;Ukončení tisku;0
))",
"exception_class": "NxError",
"error_code": 5705
}
Doplníme prázdné pole dialoginputs:
POST http://localhost:80/demo/dynsql/0QSD0SGZDTX411PSLWCG3LUGYK/exec?report=N310000001
{
"select": ["Cnt"],
"where": [
{"id": "Year", "value": "2026"},
{"id": "Code", "value": "1"}
],
"dialoginputs": []
}
Vrácený response má nyní status 422, vyvolaná chyba je EDialogsNeedValue a její součástí je:
func - volaná QR funkce
args - s jakými argumenty se volala
funcdesctiption - popis funkce
funcexample - příklad použití
Poslední dva údaje jsou shodné s nápovědou v ABRA Gen, v místech, kde se QR funkce používají (editor výrazů).
status code: 422
response headers:
==============
Date : Thu, 12 Feb 2026 09:50:27 GMT
Content-Type : application/json
Content-Length : 1165
Server : Jetty(11.0.24)
response body:
{
"title": "Chybí volba odpovědi pro dialog",
"description": "Volání dialogové funkce NxMessageBox",
"exception_class": "EDialogsNeedValue",
"error_code": 15002,
"details": {
"func": "NxMessageBox",
"args": [
"Upozornění",
"Před tiskem sestavy je třeba mít spočítané mzdové listy za mzdová období, která spadají do zpracovávaného intervalu. Pokud nebudou mzdové listy napočtené, sestava vytiskne zkreslené údaje. Přejete si v tisku pokračovat?",
3,
3,
0
],
"funcdesctiption": "NxMessageBox|Funkce pro vyvolání zprávy.
<Str1> Popis okna
<Str2> Text zprávy
<Num3> Typ zprávy
Error = 0
Warning = 1
Confirm = 2
Information = 3 (výchozí)
Exclamation = 4
Stop = 5
<Num4> Typ tlačítek
Ok = 0 (výchozí)
OkCancel = 1
RetryCancel = 2
YesNo = 3
YesNoCancel = 4
AbortRetryIgnore = 5
<Num5> index výchozího tlačítka
Vrací identifikaci zvoleného tlačítka
Ok = 1
Cancel = 2
Abort = 3
Retry = 4
Ignore = 5
Yes = 6
No = 7",
"funcexample": "NxMessageBox('Nadpis','Opravdu si chcete povyskočit?',3,3)"
}
}
Z chyby vyplývá, že se volala funkce NxMessageBox s parametry otázkou jestli chci v tisku pokračovat. Parametr číslo 4 určuje typ tlačítek (ano/ne) a funkce vrací identifikaci zvoleného tlačítka. Tlačítko Yes má hodnotu 6. Pokud tedy opravdu chceme pokračovat, pošleme v dialoginputs hodnotu 6.
POST http://localhost:80/demo/dynsql/0QSD0SGZDTX411PSLWCG3LUGYK/exec?report=N310000001
{
"select": ["Cnt"],
"where": [
{"id": "Year", "value": "2026"},
{"id": "Code", "value": "1"}
],
"dialoginputs": [6]
}
Nyní se zobrazí další chyba:
status code: 422
response headers:
==============
Date : Thu, 12 Feb 2026 10:00:26 GMT
Content-Type : application/json
Content-Length : 987
Server : Jetty(11.0.24)
response body:
==============
{
"title": "Chybí volba odpovědi pro dialog",
"description": "Volání dialogové funkce NxMessageBox",
"exception_class": "EDialogsNeedValue",
"error_code": 15002,
"details": {
"func": "NxMessageBox",
"args": [
"Dotaz",
"Přeje si také tisknout strany 3 a 4 s metodickými vysvětlivkami?",
2,
3,
2
],
"funcdesctiption": "NxMessageBox|Funkce pro vyvolání zprávy.
<Str1> Popis okna
<Str2> Text zprávy
<Num3> Typ zprávy
Error = 0
Warning = 1
Confirm = 2
Information = 3 (výchozí)
Exclamation = 4
Stop = 5
<Num4> Typ tlačítek
Ok = 0 (výchozí)
OkCancel = 1
RetryCancel = 2
YesNo = 3
YesNoCancel = 4
AbortRetryIgnore = 5
<Num5> index výchozího tlačítka
Vrací identifikaci zvoleného tlačítka
Ok = 1
Cancel = 2
Abort = 3
Retry = 4
Ignore = 5
Yes = 6
No = 7",
"funcexample": "NxMessageBox('Nadpis','Opravdu si chcete povyskočit?',3,3)"
}
}
Jedná se o stejnou QR funkci jako výše. Nyní se ptá, zda tisknout poslední 2 strany. Řekněme, že nechceme. Doplníme tedy do dialoginputs další hodnotu 7. Je to číselný kód tlačítka Ne.
POST http://localhost:80/demo/dynsql/0QSD0SGZDTX411PSLWCG3LUGYK/exec?report=N310000001
{
"select": ["Cnt"],
"where": [
{"id": "Year", "value": "2026"},
{"id": "Code", "value": "1"}
],
"dialoginputs": [6, 7]
}
Po odeslání systém hlásí další chybu:
status code: 422
response headers:
==============
Date : Thu, 12 Feb 2026 10:04:02 GMT
Content-Type : application/json
Content-Length : 505
Server : Jetty(11.0.24)
response body:
==============
{
"title": "Chybí volba odpovědi pro dialog",
"description": "Volání dialogové funkce NxInputDialog",
"exception_class": "EDialogsNeedValue",
"error_code": 15002,
"details": {
"func": "NxInputDialog",
"args": [
"Náklady na závodní prevent.péči v tis. Kč",
"Částka:",
"0"
],
"funcdesctiption": "NxInputDialog|Umožňuje zadání řetězce uživatelem.",
"funcexample": "NxInputDialog('Nadpis okna','Jmenovka','Hodnota') vrátí textový řetězec 'Hodnota',
pokud uživatel nic nezadá, nebo hodnotu zadanou uživatelem."
}
}
Tentokrát se jedná o QR funkci NxInputDialog a je potřeba zadat nějaké náklady. Z popisu funkce je zřejmé, že vrací jako výchozí hodnotu třetí parametr, tedy “0”. Pokud bychom chtěli použít tento výchozí parametr, tak do dialoginputs doplníme hodnotu null. To je obecná hodnota a pokud je použita, tak se vezme výchozí hodnota. Vždy je potřeba přečíst popis u QR funkce - ne všechny ji mají implementovanou a i pokud je implementovaná, tak se detaily můžou lišit.
V tomto případě řekněme, že nechceme výchozí hodnotu, ale vlastní. Doplňme tedy do dialoginputs hodnotu např.“1000“. V tomhle případě se může použít i číslo, protože interně se hodnoty předávají přes typ variant, který se na text zkonvertuje bez problémů.
POST http://localhost:80/demo/dynsql/0QSD0SGZDTX411PSLWCG3LUGYK/exec?report=N310000001
{
"select": ["Cnt"],
"where": [
{"id": "Year", "value": "2026"},
{"id": "Code", "value": "1"}
],
"dialoginputs": [6, 7, 1000]
}
Nyní jsou již vyplněny všechny potřebné parametry, dojde tedy k zobrazení tiskové sestavy.
JSON v odpovědích je zformátovaný kvůli čitelnosti, takže v něm můžou být z hlediska JSON formátu syntaktické chyby.
Tato funkce umožňuje zadat víc hodnot současně. Rovnou použijeme prázdné pole dialoginputs:
POST http://localhost:80/demo/dynsql/F3ZIJPWUYISO34EPXLPUETU4VO/exec?report=9R10000001
{
"select": ["id"],
"where": [
{"id": "ID", "value": "1200000101"}
],
"dialoginputs": []
}
Systém vrátí tyto informace:
status code: 422
response headers:
==============
Date : Thu, 12 Feb 2026 10:21:13 GMT
Content-Type : application/json
Content-Encoding : gzip
Content-Length : 1620
Server : Jetty(11.0.24)
response body:
==============
{
"title": "Chybí volba odpovědi pro dialog",
"description": "Volání dialogové funkce NxMultiInput",
"exception_class": "EMultiInputNeedValue",
"error_code": 15002,
"details": {
"func": "NxMultiInput",
"args": [
500,
90,
"Zadejte údaje (006: Kusá Eva (785306/0226) - HPP: Hlavní PP)",
"label,6,14,100,20,Druh dokladu:; enum,RpParType,110,12,200,24,Nástup do zaměstnání:Skončení zaměstnání:Změna údajů:Oprava údajů:Převod:Vznik příslušnosti k CZ pr. předpisům:Ukončení přísl. k CZ pr. předpisům,0; label,6,38,100,20,Druh zaměstnání:; enum,RpRelationType,110,36,200,24,Pracovněprávní vztah:Služební poměr podle zákova č. 234/2014 Sb.,0; label,6,62,81,13,Datum změn:; date,RpParDate,110,60,100,24,46065",
"",
""
],
"funcdesctiption": "NxMultiInput|Funkce pro vytvoření editačního formuláře pro více údajů.
<Num1> šířka plochy s editačními prvky
<Num2> výška plochy s editačními prvky
<Str3> záhlaví formuláře
<Str4> definice editačních prvků
[<Str5>] prefix pro uložení hodnot
[<Str6>] volitelný seznam názvů prvků pro uložení hodnot (oddělují se ",")
pokud zadáte prefix, bude si dialog pamatovat zadané hodnoty a přednabízet je při dalším použití
Definice prvků:
- jednotlivé prvky se oddělují středníkem
- vlastnosti jednotlivých prvků se oddělují čárkou
- hodnoty enumerační položky se oddělují dvojtečkou
Možné typy editačních prvků:
- text - znaková položka
text,název,x,y,šířka,výška,[výchozí hodnota]
- number - číselná položka
number,název,x,y,šířka,výška,počet cifer,des. místa,[výchozí hodnota]
- date - datumová položka
date,název,x,y,šířka,výška,[výchozí hodnota]
- bool - Ano/Ne položka
bool,název,x,y,šířka,výška,popisek,[výchozí hodnota]
- enum - Ano/Ne položka
enum,název,x,y,šířka,výška,položka1:položka2:položka3:...položkaN,[výchozí hodnota]
- label - nápis
label,x,y,šířka,výška,text
- roll - vybrání hodnoty z číselníku
roll,název,x,y,šířka,výška,GUID číselníku,[vyhledávaná položka číselníku,zobrazovaná
položka číselníku,šířka prvku pro zobrazení "zobrazované" položky číselníku]
V textových popisech není možné používat znak čárka (je separátorem).
Místo čárky použijte zástupnou entitu &c .",
"funcexample": "NxMultiInput(600,300,'Zadejte údaje',
'label,6,6,100,20,Velikost košile:;
number,VELIKOST,110,6,100,24,2,0,42;
label,6,31,100,20,Typ:;
enum,TYP,110,31,80,24,Pánská:Dámská:Dětská,1;
label,6,50,81,13,Firma:;
roll,firm,110,50,121,21,O3OWQQYWYJCL3J0B01K0LEIOE0,Code,Name,240;')
Hodnota se pak vyzvedává pomocí funkce NxGetParamValue
Příklad: NxGetParamValue('VELIKOST') vrátí hodnotu zadanou do numerického vstupu VELIKOST.",
"definition": [
{
"type": "label",
"left": 6,
"top": 14,
"width": 100,
"height": 20,
"caption": "Druh dokladu:"
},
{
"name": "RpParType",
"type": "enum",
"left": 110,
"top": 12,
"width": 200,
"height": 24,
"items": [
"Nástup do zaměstnání",
"Skončení zaměstnání",
"Změna údajů",
"Oprava údajů",
"Převod",
"Vznik příslušnosti k CZ pr. předpisům",
"Ukončení přísl. k CZ pr. předpisům"
],
"defaultIndex": 0
},
{
"type": "label",
"left": 6,
"top": 38,
"width": 100,
"height": 20,
"caption": "Druh zaměstnání:"
},
{
"name": "RpRelationType",
"type": "enum",
"left": 110,
"top": 36,
"width": 200,
"height": 24,
"items": [
"Pracovněprávní vztah",
"Služební poměr podle zákova č. 234/2014 Sb."
],
"defaultIndex": 0
},
{
"type": "label",
"left": 6,
"top": 62,
"width": 81,
"height": 13,
"caption": "Datum změn:"
},
{
"name": "RpParDate",
"type": "date",
"left": 110,
"top": 60,
"width": 100,
"height": 24,
"defaultValue": "2026-02-11T23:00:00.000Z"
}
]
}
}
Chyba je ve stejném formátu jako předchozí a v parametru číslo 4 je definice vstupů formuláře. Protože se jedná o interní, textový, těžko, čitelný formát, má odpověď navíc ještě hodnotu "definition", kde je tento formát převedený do JSON podoby.
Odpověď na tento dialog je JSON objekt typu slovník - klíče jsou hodnoty z definice pod názvem “name“ a vlastní hodnotu přidá klient, např. takto:
POST http://localhost:80/demo/dynsql/F3ZIJPWUYISO34EPXLPUETU4VO/exec?report=9R10000001
{
"select": ["id"],
"where": [
{"id": "ID", "value": "1200000101"}
],
"dialoginputs": [{"RpParType": 4, "RpRelationType": 1, "RpParDate": 46054}]
}
Nyní se zobrazí další chyba:
status code: 422
response headers:
==============
Date : Thu, 12 Feb 2026 10:00:26 GMT
Content-Type : application/json
Content-Length : 987
Server : Jetty(11.0.24)
response body:
==============
{
"title": "Chybí volba odpovědi pro dialog",
"description": "Volání dialogové funkce NxMessageBox",
"exception_class": "EDialogsNeedValue",
"error_code": 15002,
"details": {
"func": "NxMessageBox",
"args": [
"Dotaz",
"Přeje si také tisknout strany 3 a 4 s metodickými vysvětlivkami?",
2,
3,
2
],
"funcdesctiption": "NxMessageBox|Funkce pro vyvolání zprávy.
<Str1> Popis okna
<Str2> Text zprávy
<Num3> Typ zprávy
Error = 0
Warning = 1
Confirm = 2
Information = 3 (výchozí)
Exclamation = 4
Stop = 5
<Num4> Typ tlačítek
Ok = 0 (výchozí)
OkCancel = 1
RetryCancel = 2
YesNo = 3
YesNoCancel = 4
AbortRetryIgnore = 5
<Num5> index výchozího tlačítka
Vrací identifikaci zvoleného tlačítka
Ok = 1
Cancel = 2
Abort = 3
Retry = 4
Ignore = 5
Yes = 6
No = 7",
"funcexample": "NxMessageBox('Nadpis','Opravdu si chcete povyskočit?',3,3)"
}
}
Jedná se o stejnou QR funkci jako výše. Nyní se ptá, zda tisknout poslední 2 strany. Řekněme, že nechceme. Doplníme tedy do dialoginputs další hodnotu 7. Je to číselný kód tlačítka Ne.
POST http://localhost:80/demo/dynsql/0QSD0SGZDTX411PSLWCG3LUGYK/exec?report=N310000001
{
"select": ["Cnt"],
"where": [
{"id": "Year", "value": "2026"},
{"id": "Code", "value": "1"}
],
"dialoginputs": [6, 7]
}
Po odeslání systém hlásí další chybu:
status code: 422
response headers:
==============
Date : Thu, 12 Feb 2026 10:04:02 GMT
Content-Type : application/json
Content-Length : 505
Server : Jetty(11.0.24)
response body:
==============
{
"title": "Chybí volba odpovědi pro dialog",
"description": "Volání dialogové funkce NxInputDialog",
"exception_class": "EDialogsNeedValue",
"error_code": 15002,
"details": {
"func": "NxInputDialog",
"args": [
"Náklady na závodní prevent.péči v tis. Kč",
"Částka:",
"0"
],
"funcdesctiption": "NxInputDialog|Umožňuje zadání řetězce uživatelem.",
"funcexample": "NxInputDialog('Nadpis okna','Jmenovka','Hodnota') vrátí textový řetězec 'Hodnota',
pokud uživatel nic nezadá, nebo hodnotu zadanou uživatelem."
}
}
Tentokrát se jedná o QR funkci NxInputDialog a je potřeba zadat nějaké náklady. Z popisu funkce je zřejmé, že vrací jako výchozí hodnotu třetí parametr, tedy “0”. Pokud bychom chtěli použít tento výchozí parametr, tak do dialoginputs doplníme hodnotu null. To je obecná hodnota a pokud je použita, tak se vezme výchozí hodnota. Vždy je potřeba přečíst popis u QR funkce - ne všechny ji mají implementovanou a i pokud je implementovaná, tak se detaily můžou lišit.
V tomto případě řekněme, že nechceme výchozí hodnotu, ale vlastní. Doplňme tedy do dialoginputs hodnotu např.“1000“. V tomhle případě se může použít i číslo, protože interně se hodnoty předávají přes typ variant, který se na text zkonvertuje bez problémů.
POST http://localhost:80/demo/dynsql/0QSD0SGZDTX411PSLWCG3LUGYK/exec?report=N310000001
{
"select": ["Cnt"],
"where": [
{"id": "Year", "value": "2026"},
{"id": "Code", "value": "1"}
],
"dialoginputs": [6, 7, 1000]
}
Nyní jsou již vyplněny všechny potřebné parametry, dojde tedy k zobrazení tiskové sestavy.
Uživatel si tedy může připravit klienta, který bude status 422 interpretovat a předkládat klientovi a jeho odpovědi postupně skládat do dialoginputs. Anebo si může pro nějakou sestavu hodnoty pro dialoginputs zjistit a pak je používat napevno. Pokud se ale sestava změní, bude je muset znovu zjistit. Kód jako takový je přímo v QR funkcích a je jedno, jestli se funkce vyvolá z tisku, exportu nebo něčeho jiného.
Tisk revizí probíhá stejně jako standardní tisk, jen za kontrolerem bude ID konkrétní revize dokladu.
Například máme-li doklad s aktuální revizí ID 2020000101 a revizí, která má ID 4020000101 a potřebujeme-li tisknout revizi s ID 4020000101 do PDF, použijeme následující dotaz
GET http://localhost:699/demodata/issuedinvoices/4020000101.pdf?select=id&report=W400000001
Pokud je zapotřebí vytisknout více záznamů než jeden, stačí odpovídajícím způsobem upravit klauzuli WHERE, aby při zpracování požadavku byla vybrána požadovaná skupina záznamů (v souladu s pravidly zápisu používanými v jednotlivých způsobech dotazování).
Základní dotazování - úprava URL:
GET http://localhost:699/demodata/issuedinvoices?select=id&where=id+in+('8M00000101','1O00000101')&report=W400000001
Rozšířené dotazování - úprava těla POST požadavku:
{
"class": "issuedinvoices",
"select": "id",
"where": "id in ('8M00000101','1O00000101')"
}
Výše uvedené příklady předpokládají, že známe ID tiskové sestavy, kterou chceme k tisku použít. Tento údaj můžeme zjistit několika způsoby - přímo v systému ABRA Gen nebo prostřednictvím jiných nástrojů.
Jedná se o nejjednodušší způsob, pokud máme k dispozici systém ABRA Gen a chceme uživateli umožnit z API vytisknout určitou konkrétní sestavu.
Na místě, kde se požadovaná tisková sestava nachází (typicky na záložce Seznam příslušné agendy), použijeme klávesovou zkratku ctrl+I, která ID tiskové sestavy, na které máme focus, uloží do schránky Windows, z které je pak možné ID vložit do API požadavku (například pomocí klávesové zkratky ctrl+V). Nebo je možné použít funkci Tisk: Po výběru požadované množiny záznamů k tisku se zobrazí výběrový číselník tiskových sestav přiřazených k programovému místu, které odpovídá dané agendě. Kliknutím na záhlaví sloupců pravým tlačítkem vyvoláme lokální menu, ze kterého vybereme nástroj Editor sloupců a následně funkcí Nový sloupec do seznamu doplníme sloupec ID jako jednu z položek business objektu Tisková sestava. Takto získané ID můžeme následně použít v požadavku API, jak je uvedeno v příkladech výše.
Systémová tisková sestava Formulář faktury vydané má ID W400000001.
Hledání podle názvu
ID tiskové sestavy můžeme získat přímo z Web API, pokud jej dokážeme dohledat podle nějakého identifikátoru. Pokud například víme, že hledáme sestavu týkající se dobropisů, můžeme zaslat požadavek
GET http://localhost:699/demodata/reports?select=id,displayname&where=title+like+'*dobropis*'
a ve výsledku získat seznam ID všech tiskových sestav vyhovujících omezující podmínce.
Dotazování na řetězce a jejich části prostřednictvím Web API tímto způsobem zohledňuje velikost písmen (je case sensitive
Je-li nějaká položka case insensitive, znamená to, že není citlivá na velká a malá písmena, neboli nerozlišuje velká a malá písmena. Tzn., že není rozdíl, je-li napsáno např. "Abc" nebo "abc". Opak je case sensitive.). Pokud bychom ve výše uvedeném případě v klauzuli where použili řetězec *Dobropis* nebo *DOBROPIS*, nanalezli bychom pravděpodobně nic. Ve výrazu nicméně můžeme použít funkci upper() nebo lower(), které tento problém řeší:
GET http://localhost:699/demodata/reports?select=id,displayname&where=lower(title)+like+'*dobropis*'
Při dotazování můžeme také zohlednit viditelnost (aktuálnost) tiskových sestav. Pokud bychom chtěli získat pouze sestavy viditelné k datu 12. 3. 2019, upravili bychom požadavek následovně:
GET http://localhost:699/demodata/reports?select=id,displayname&where=title+like+'*dobropis*'+and+(visibleto$date+eq+0+or+visibleto$date+ge+timestamp'2019-03-12')+and+(visiblefrom$date+eq+0+or+visiblefrom$date+le+timestamp'2019-03-12')
Podmínka visibleto$date+eq+0 znamená "položka Viditelnost do není vyplněna". Způsob zápisu odpovídá způsobu uložení dat v databázi.
Hledání podle datového zdroje
Praktičtější může být hledání (příp. omezování výběru) tiskových sestav podle datového zdroje.
Tiskové sestavy se v systému ABRA Gen volají z různých míst, kterým říkáme programová místa, a ke každému takovému programovému místu může být přiřazen jeden nebo několik dynamických zdrojů dat (DynSQL). Jednou z vlastností každé tiskové sestavy je identifikace datového zdroje, ze kterého sestava čerpá data.
Identifikaci programových míst je možné nalézt v technické dokumentaci, konkrétně v popisu struktur a definic, ve kterém je pro každý modul uvedený Seznam programových bodů.
Programový bod (ProgPoint) a Programové místo jsou synonyma.
Pokud tedy potřebujeme získat seznam datových zdrojů používaných v sestavách faktur vydaných, vyhledáme ve zmíněném popisu struktur a definic programové místo (programový bod) Faktury vydané a zjistíme, že je k němu přiřazený jediný dynamický zdroj dat s ID 40SBPEINEFD13ACM03KIU0CLP4.
Seznam tiskových sestav využívajících tento zdroj dat pak získáme následujícím způsobem:
GET http://localhost:699/demodata/reports?select=id,displayname&where=datasource+eq+'40SBPEINEFD13ACM03KIU0CLP4'
Díky této možnosti lze například uživateli aplikace využívající Web API nabídnout aktuální seznam dostupných sestav použitelných v daném kontextu, ze kterých si uživatel dle vlastních preferencí některou vybere a použije k tisku.
V popisu struktur a definic je možné nalézt pouze identifikátory systémových dynamických zdrojů dat přiřazených k systémovým programovým místům. Tato oblast systému je však uživatelsky modifikovatelná - je možné definovat vlastní dynamické zdroje dat, případně i vlastní programová místa nebo reportingové skupiny.
Typickým případem je situace, kdy systémový datový zdroj nenabízí určité informace, které v sestavě potřebujeme zobrazovat, proto si systémový datový zdroj zkopírujeme do uživatelského datového zdroje, rozšíříme dle potřeby, přidáme ke stejnému programovému místu, ke kterému je přiřazený původní systémový datový zdroj a nakonec vytvoříme tiskovou sestavu, ve které jako Zdroj dat nastavíme nově vytvořený datový zdroj.
Přidělené ID uživatelského zdroje zjistíme v nástroji DynSQLEditor, ve kterém se uživatelské datové zdroje definují - konkrétně na záložce Dynamické SQL pod seznamem Dynamické SQL příkazy pod označením ID příkazu (packed GUID).
Takto zjištěné ID datového zdroje můžeme následně použít k výběru tiskových sestav, které z příslušného zdroje čerpají data, stejně jako v případě systémových dynamických zdrojů dat, jejichž ID můžeme kromě DynSQLEditoru zjistit také v popisu struktur a definic.
Uvedený způsob můžeme alternativně použít ve všech případech místo hledání v popisu struktur a definic:
- v DynSQLEditoru použijeme funkci Importovat vše
- na záložce Místa v programu vyhledáme příslušné místo (v našem případě Faktury vydané)
- v panelu Seznam dynamických SQL je zobrazen seznam všech systémových i uživatelských dynamických zdrojů dat, které jsou k danému programovému místu přiřazeny
Pro generování definovatelných exportů a B2B exportů platí obdobné principy jako pro generování tiskových sestav. Rozdíly a rozšíření:
-
Místo query parametru report se používá query parametr export, ve kterém se specifikuje ID definovatelného exportu nebo B2B exportu.
GET http://localhost:699/demodata/workingrelations?select=id&where=id+eq+'5100000101'&export=I300000001 -
Pro B2B export je v URL zapotřebí použít další query parametr b2b, kterým se rozliší, zda se požadavek týká definovatelného exportu nebo B2B exportu.
- b2b=false - požadavek na vygenerování definovatelného exportu (výchozí hodnota)
- b2b=true - požadavek na vygenerování B2B exportu
GET http://localhost:699/demodata/issuedinvoices?select=id&where=id+eq+'8M00000101'&export=F000000001&b2b=true
Generování definovatelných exportů a B2B exportů je odvozeno od generování tiskových sestav a z tohoto důvodu je obdobně jako v případě tiskových sestav zapotřebí některým z uvedených dvou způsobů specifikovat výstupní formát.
Výstupní formát nemá v případě exportů věcný význam, neboť výsledkem zpracování požadavku jsou vždy strukturovaná data v podobě jednoznačně dané definicí exportu. Nicméně stejně jako v případě generování tiskových sestav, pokud se formát nespecifikuje, výsledkem zpracování HTTP požadavku jsou data ve formátu JSON (jako by se nejednalo o požadavek na export, ale standardní dotazování do dat). Z tohoto důvodu je zapotřebí i u exportů prostřednictvím Content negotiation nebo přípony u názvu kolekce v URL specifikovat některý z trojice formátů PDF, XLSX nebo CSV.
Následující požadavek
GET http://localhost:699/demodata/workingrelations.pdf?select=id&where=id+eq+'5100000101'&export=I300000001
sice nevrátí PDF soubor, ale bez uvedení formátu (libovolného podporovaného formátu z uvedené trojice) se export nevygeneruje.