HotPDF ustvarja, zaznava in potrjuje elektronske račune ZUGFeRD in Factur-X iz Delphija in C++Builderja. Metoda AddFacturXAssociatedFile vgradi XML e-računa po EN 16931 v vsebnik PDF/A-3, DetectFacturXInvoice prepozna dohodni hibridni račun, HPDFValidateEInvoice pa izvede uradna poslovna pravila EN 16931 Schematron nad vgrajenim XML-jem. Ta članek opisuje vse tri korake in iskreno predstavi omejitve potrditvenega pogona
Pritisk za uvedbo tega nabora funkcij je regulativne in ne tehnične narave. Nemčija in Francija postopoma uvajata obvezno strukturirano e-izdajanje računov za domače transakcije B2B, pri čemer se obe zakonodaji stekata v isti hibridni model: račun PDF, ki ga vaš sistem ERP že ustvari, mora vsebovati strojno berljiv XML-dvojnik. Aplikacije za računovodstvo ali sisteme ERP v Delphiju, ki danes izdajajo navadne račune PDF, imajo strog rok za začetek izdajanja Factur-X ali ZUGFeRD. Razlika med obema imenoma pa je manjša, kot kaže trženje — Factur-X in ZUGFeRD sta isti francosko-nemški standard, izdan pod dvema različnima oznakama
Kaj naredi PDF veljaven račun Factur-X?
Veljaven račun Factur-X je datoteka PDF/A-3 (ISO 19005-3), ki kot povezano datoteko vgrajuje natanko en strukturiran XML e-računa, ga povezuje iz kataloga dokumentov in ga deklarira v metapodatkih razširitve XMP. Tri ravni se morajo ujemati. Prvič, vsebnik mora ustrezati standardu PDF/A-3, to je arhivski profil, ki – za razliko od PDF/A-1 in PDF/A-2 – omogoča vgradnjo datotek katere koli vrste. Drugič, XML e-računa z imenom factur-x.xml za standardne profile ali xrechnung.xml za nemško različico XRechnung, mora biti registriran v matriki kataloga /AF ter v drevesu /Names /EmbeddedFiles z vnosom AFRelationship, ki pove, kaj priloga predstavlja: Alternative pomeni, da je XML enakovredna predstavitev vidnega računa, kar je semantika, ki jo zahteva večina profilov. Tretjič, shema razširitve Factur-X XMP mora poimenovati vgrajeno datoteko, njeno raven skladnosti in vrsto dokumenta, tako da lahko sprejemni sistem razvrsti račun, ne da bi sploh razčlenil XML
Sama vsebina XML sledi semantičnemu modelu EN 16931, evropskemu standardu, ki opredeljuje jedro računa: kupec, prodajalec, postavke, razčlenitev davkov, znesek za plačilo, vsak s številko poslovnega izraza (BT-1 za številko računa, BT-5 za valuto in tako naprej). Potrjevanje EN 16931 zato poteka na dveh ločenih ravneh. Validacija sheme XML preverja, ali je dokument pravilno oblikovan CII s pravimi imeni elementov. Poslovna pravila Schematron preverjo, ali je vsebina skladna — da velja BR-CO-15 in da je skupni znesek računa dejansko enak vsoti neto zneskov postavk plus DDV ter da so prisotni obvezni izrazi za deklarirani profil. Datoteka lahko prestane validacijo sheme, pa je še vedno neveljaven račun, zato obstaja raven poslovnih pravil
Zakaj ZUGFeRD 2.5 ne potrebuje novega vsebnika
ZUGFeRD 2.5 ne spreminja ničesar na ravni vsebnika PDF: smernice URN, shema XMP in oznaka različice so enake kot pri ZUGFeRD 2.3 / Factur-X 1.0. To preseneča večino implementatorjev, zato je vredno navesti vir. Specifikacija Factur-X 1.09 navaja, da številka različice v URI razširitvene sheme PDF/A ni povezana s številko različice specifikacije podatkov XML in da različica primerkov računov Factur-X ostaja 1.0 — tako v XMP fx:Version kot v BT-24 datoteke factur-x.xml. Uradna zbirka vzorcev ZUGFeRD 2.5 to potrjuje: vsak vzorec vgrajuje factur-x.xml pod smernico URN urn:factur-x.eu:1p0 z fx:Version z vrednostjo 1.0. Kar 2.5 dejansko prinaša, se nahaja znotraj podatkovnega modela XML — novi elementi, kot so vrstice podračunov in identifikatorji serij —, kar pa je poslovni sloj, ki ga ustvari vaša aplikacija, in ne sloj vsebnika, ki ga upravlja knjižnica PDF
HotPDF to ugotovitev neposredno kodira. Metoda AddFacturXAssociatedFile sprejme argument Version in ga pred pisanjem XMP normalizira prek HPDFFacturXNormalizeVersion, tako da klicatelja, ki posreduje alias 2p5, še vedno odda oznako, skladno s specifikacijo, namesto da bi si izmislil različico XMP 2p5, ki je noben validator ne bi sprejel. Pomočniki za zaznavanje pri branju obravnavajo 2p5 kot enakovredno različico, tako da dvosmerni prehodi ostajajo simetrični. Če vam kakšna knjižnica ali orodje trdi, da piše poseben vsebnik ZUGFeRD 2.5, sama specifikacija pravi, da kaj takega ne obstaja
Vgradnja XML računa iz Delphija
Metoda THotPDF.AddFacturXAssociatedFile z enim samim klicem spremeni običajno ustvarjanje PDF/A-3 v račun Factur-X: vgradi bajte XML kot povezano datoteko, registrira factur-x.xml v matriki kataloga /AF in v drevesu /Names /EmbeddedFiles ter odda ustrezne metapodatke razširitve Factur-X XMP. Človeško berljivo stran računa narišete z običajnim API-jem za platno HotPDF; delo z vsebnikom pa je ena sama vrstica med BeginDoc in EndDoc
var
Pdf: THotPDF;
InvoiceXML, UBLXML: TBytes;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'invoice-2026-0042.pdf';
Pdf.PDFACompliance := '3B'; // PDF/A-3b container
Pdf.BeginDoc;
// embed the EN 16931 CII invoice XML as factur-x.xml
InvoiceXML := BuildInvoiceXML; // produced by your business layer
Pdf.AddFacturXAssociatedFile(InvoiceXML, 'EN 16931');
// optional: attach a UBL view as a supplementary representation
UBLXML := BuildUBLXML;
Pdf.AddUBLSupplementaryFile(UBLXML); // factur-xubl.xml, Alternative
// ... draw the visible invoice page here ...
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Privzete nastavitve sledijo specifikaciji: ime datoteke factur-x.xml, razmerje Alternative, različica 1.0. Metoda AddUBLSupplementaryFile implementira razdelek 6.4 specifikacije Factur-X 1.09, ki omogoča, da se predstavitev UBL istega računa priloži kot druga priloga z imenom factur-xubl.xml z vrsto MIME application/xml and razmerjem Alternative. Vrstni red je tukaj pomemben in HotPDF uveljavlja omejitev, ki jo implicira specifikacija: datoteka UBL je dopolnilni pogled, nikoli primarni račun, zato jo je treba dodati po tem, ko je AddFacturXAssociatedFile že registriral CII glavnik (master). Upoštevajte, da morata izrisana stran in vgrajeni XML navajati isti račun — PDF, ki prikazuje en znesek in kodira drugega, je natanko tisti neuspešni primer, ki ga hibridno izdajanje računov želi preprečiti. Stran PDF/A-3 tega delovnega toka, vključno z OutputIntent in vgradnjo pisav, je podrobneje obravnavana v spremljevalnem članku o potrjevanju PDF/A, PDF/X in PDF/UA v Delphiju
Kako zaznati račun Factur-X v dohodnem PDF-ju?
Metoda THotPDF.DetectFacturXInvoice odgovarja na sprejemno stran zakonodaje: naložite kateri koli PDF in z enim klicem ugotovite, ali gre za hibridni račun, kateri profil deklarira in katere priloge vsebuje. Funkcija vrne zapis THPDFFacturXInvoiceInfo z imenom vgrajene datoteke XML, imenom in vrsto datoteke dokumenta, deklariranima v XMP, oznako različice, ravnijo skladnosti, smernico URN in vrednostjo AFRelationship. Dve dodatni polji poročata o dopolnilnih pogledih: UBLFileName se napolni, ko je prisotna priloga factur-xubl.xml, EDIFACTFileName pa, ko je priložen pogled EDIFACT — noben od njiju ne vpliva na oceno zaznave, saj dopolnilna predstavitev ne more obstajati brez primarnega CII računa
var
Reader: THotPDF;
Info: THPDFFacturXInvoiceInfo;
begin
Reader := THotPDF.Create(nil);
try
if Reader.LoadFromFile('incoming-invoice.pdf') <= 0 then
raise Exception.Create('No pages loaded.');
if Reader.DetectFacturXInvoice(Info) then
begin
Writeln('Invoice XML: ', string(Info.FileName));
Writeln('Conformance: ', string(Info.ConformanceLevel));
Writeln('Guideline URN: ', string(Info.GuidelineID));
Writeln('Relationship: ', string(Info.AFRelationship));
if Info.UBLFileName <> '' then
Writeln('UBL view: ', string(Info.UBLFileName));
end
else
Writeln('Not a Factur-X / ZUGFeRD hybrid invoice.');
finally
Reader.Free;
end;
end;
Zaznavanje bere enake signale, kot jih bere skladen validator — shemo razširitve XMP in register povezanih datotek —, namesto da bi ugibalo le na podlagi imen datotek. Isti objekt naloženega dokumenta izpostavlja tudi metapodatke XMP in slovarja Info za pregled ali popravke, kar je delovni tok, opisan v članku o urejanju metapodatkov v naloženih PDF dokumentih
Poslovna pravila ali shema: kaj pomeni validacija EN 16931?
Funkcija HPDFValidateEInvoice, samostojna funkcija v enoti HPDFEInvoiceValidator, zaporedoma zažene obe potrditveni ravni: najprej preverjanje strukture vsebnika prek ValidateFacturXInvoice, nato pa še poslovna pravila EN 16931 Schematron nad izvlečenim XML e-računa. HotPDF prinaša pet uradnih datotek s pravili Factur-X 1.09 — MINIMUM, BASIC WL, BASIC, EN 16931 in EXTENDED — pod Lib/resources/Schematron/, metoda HPDFSchematronFileForProfile pa izbere datoteko, ki se ujema z zaznano ravnijo skladnosti, tako da se račun EN 16931 samodejno preveri proti Factur-X_1.09_EN16931.sch. Funkcija vrne True le, ko je vsebnik veljaven in se ni sprožilo nobeno poslovno pravilo
uses HPDFEInvoiceValidator;
var
Reader: THotPDF;
Report: THPDFEInvoiceValidationReport;
I: Integer;
begin
Reader := THotPDF.Create(nil);
try
Reader.LoadFromFile('incoming-invoice.pdf');
if HPDFValidateEInvoice(Reader, SchematronDir, Report) then
Writeln('Container and business rules: OK')
else
Writeln('Validation found issues.');
if Report.BusinessRulesEvaluated then
begin
Writeln(Report.BusinessSummary.Evaluated, ' rules evaluated, ',
Report.BusinessSummary.Skipped, ' skipped (XPath 2.0)');
for I := 0 to High(Report.BusinessRules) do
if (not Report.BusinessRules[I].Skipped) and
(Report.BusinessRules[I].Severity = stsError) then
Writeln(string(Report.BusinessRules[I].RuleID), ': ',
string(Report.BusinessRules[I].Message));
end;
finally
Reader.Free;
end;
end;
Vsak vnos v BusinessRules prenaša identifikator pravila, razčlenjen iz besedila trditve — BR-45, BR-CO-17 in preostale dele poimenovanja EN 16931 —, ter kontekstni XPath pravila, testni izraz in resnost, ki zrcali atribut zastavice (flag) v Schematronu. Zaradi tega je poročilo uporabno: namesto golega uspel/spodletel dobite natančen poslovni izraz, ki ni skladen, kar vaša ekipa za podporo potrebuje, ko stranka vpraša, zakaj je bil račun zavrnjen. Ekipe, ki že ustvarjajo strukturirana poročila o skladnosti za arhivske PDF-je, lahko te rezultate vključijo v isti cevovod, opisan v članku o avtomatizaciji poročil o predpoletnem pregledu (preflight) PDF-jev
Kje se validator iskreno ustavi
Pogon Schematron temelji na MSXML, ki vrednoti XPath 1.0. Datoteka s pravili EN 16931 deklarira queryBinding="xslt2" in vsebuje 424 trditev, od katerih večina uporablja le funkcije XPath 1.0, kot sta string-length in substring-after — te se izvajajo izvorno. Manjšina se opira na konstrukcije XPath 2.0, kot so pretvorbe tipov xs:decimal ali exists(); HotPDF vnaprej pregleda vsak testni izraz za znane žetone XPath 2.0 in ta pravila označi kot preskočena (Skipped) z resnostjo info, namesto da bi poskušal izvesti vrednotenje, ki bi se tiho ponesrečilo. Zbirni zapis poroča o številu ovrednotenih in preskočenih pravil ločeno, tako da vaš dnevnik vedno natančno navaja, kolikšen del nabora pravil je bil uporabljen. V Delphiju 7, kjer vezave MSXML niso na voljo, enota prevede škrbino (stub), ki poroča, da pogon ni na voljo, ne da bi motila oceno vsebnika; celoten pogon zahteva Delphi XE2 ali novejši
Druga meja je še pomembnejša. Zeleni rezultat funkcije HPDFValidateEInvoice pomeni, da je struktura vsebnika skladna in da se ni sprožilo nobeno od ovrednotenih poslovnih pravil — to ni davčna potrditev. Nacionalna pravila razširitev, prejemniku specifične zahteve in zakonske obveznosti glede vsebine računov se nahajajo nad jedrom EN 16931 in zunaj katere koli knjižnice. Validator obravnavajte kot vratarja, ki preprečuje, da bi strukturno pokvarjeni računi zapustili vaš predal za odhodno pošto, in označuje neskladne v predalu za dohodno pošto. Ko certifikacija to zahteva, v svojem izdajateljskem cevovodu zaženite celoten validator XPath 2.0, vprašanje davčne skladnosti pa prepustite svojim davčnim svetovalcem. API-ji za vgradnjo, zaznavanje in potrjevanje, prikazani tukaj, so del standardne komponente HotPDF Component za Delphi in C++Builder, s celotnim vzorcem e-računov, ki pokriva vseh sedem profilov ZUGFeRD in Factur-X