Tehnicki clanak

PDF/A-3 prosirene seme za Factur-X XMP u Delphi-ju

Izgradili ste Factur-X fakturu i svaka provera kontejnera prolazi. Katalog nosi /AF niz, stablo naziva EmbeddedFiles razresava se na ispravnu specifikaciju datoteke, ugradeni factur-x.xml ima ispravan /AFRelationship od Alternative, a ugradeni ValidateFacturXInvoice vraca 1. Zatim pokrenete istu datoteku kroz veraPDF, referentni proverac koji poreski portali koriste, i on proglasi ceo dokument nevazecim PDF/A-3. Struktura je ispravna. Metapodaci su problem, a neuspeh je jedan od najlaksih u celom toku rada sa e-fakturama za propustiti

Razlog je vredno razumeti u potpunosti, jer objasnjava klasu PDF/A nedostataka koji nemaju nikakve veze sa vidljivom stranicom ili privitkom i sve sa tim kako XMP opisuje sebe. Ovo je zamka koja se skriva iza zelene provere kontejnera

Cetiri svojstva koja ne prolaze datoteku

Factur-X faktura zapisuje cetiri prilagodjena svojstva u svoj XMP paket kako bi downstream softver mogao citati profil fakture bez parsiranja ugradenog XML-a. Ona zive u Factur-X imenskom prostoru pod prefiksom fx: fx:DocumentFileName, fx:DocumentType, fx:Version i fx:ConformanceLevel. To su tacno metapodaci koji su citaocu potrebni da zna da ovaj PDF nosi EN 16931 fakturu nazvanu factur-x.xml na verziji 1.0

Nijedno od ta cetiri svojstva nije deo bilo koje XMP seme koju PDF/A predefiniše. Dublin Core, XMP Basic, PDF i PDF/A seme identifikacije su poznate konformnom citaocu, ali fx: nije. Kada veraPDF prodje kroz XMP i dodje do svojstva ciji imenski prostor ne prepoznaje, trazi deklaraciju koja bi mu rekla sta to svojstvo znaci. Ako ta deklaracija nedostaje, prijavljuje neuspeh prema ISO 19005-3 klauzuli 6.6.2.3.1, koja zahteva da svako svojstvo koje nije crpljeno iz predefinisane seme bude opisano u PDF/A prosirenoj semi. Cetiri nedeklarisana svojstva, cetiri nacina na koji datoteka moze biti odbijena, i nijedno od njih nije vidljivo proveri kontejnera

Zasto PDF/A odbija golo prilagodjeno svojstvo

Pravilo izgleda pedantno dok ne zapamtite cemu sluzi PDF/A. Format postoji kako bi datoteka mogla biti otvorena i shvacena desetljecima od sada, softverom koji nikada nije bio obavestem o konvencijama iz 2026. Od konformnog citaoca se ocekuje da razume dokument samo iz dokumenta, bez spoljnog registra za konsultovanje

Prilagodjena metapodaci narusavaju to obecanje osim ako datoteka ne nosi vlastiti opis. Sa golim fx:ConformanceLevel svojstvom, buduci citalac ne moze znati URI imenskog prostora na koji prefiks fx ukazuje, da li je vrednost tekst ili datum ili ceo broj, ili da li svojstvo opisuje sam dokument ili neki spoljni resurs. Mehanizam PDF/A proširene seme zatvara taj jaz. On dozvoljava datoteci da deklarise, u fiksnoj XMP strukturi, imenski prostor, prefiks i za svako svojstvo tip vrednosti i kategoriju od internal ili external. Kada je ta deklaracija prisutna, svojstvo je samoopiszujuce, a klauzula 6.6.2.3.1 je zadovoljena. Bez nje, validator nema drugog izbora nego tretirati svojstvo kao nerazumljivo i odbaciti datoteku. Razlika kategorija je ovde vazna: svojstva fakture kao ova opisuju podatke koji dolaze izvana PDF procesora, pa se deklarisu kao external a ne internal

Sta sadrzi deklaracija prosirene seme

Deklaracija je rdf:Description u XMP paketu koji koristi tri AIIM-definisana imenskog prostora pdfaExtension, pdfaSchema i pdfaProperty. Unutar pdfaExtension:schemas vrece sedi jedan unos seme koji imenuje Factur-X semu, daje njen pdfaSchema:namespaceURI i pdfaSchema:prefix, a zatim nabraja cetiri svojstva u pdfaSchema:property sekvenci. Svako svojstvo nosi ime, pdfaProperty:valueType od Text, i pdfaProperty:category od external. Ilustrativni markup ispod pokazuje oblik tog bloka

<rdf:Description rdf:about=""
    xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
    xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
    xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">
  <pdfaExtension:schemas>
    <rdf:Bag>
      <rdf:li rdf:parseType="Resource">
        <pdfaSchema:schema>Factur-X PDFA Extension Schema</pdfaSchema:schema>
        <pdfaSchema:namespaceURI>urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#</pdfaSchema:namespaceURI>
        <pdfaSchema:prefix>fx</pdfaSchema:prefix>
        <pdfaSchema:property>
          <rdf:Seq>
            <rdf:li rdf:parseType="Resource">
              <pdfaProperty:name>DocumentFileName</pdfaProperty:name>
              <pdfaProperty:valueType>Text</pdfaProperty:valueType>
              <pdfaProperty:category>external</pdfaProperty:category>
              <pdfaProperty:description>name of the embedded XML invoice file</pdfaProperty:description>
            </rdf:li>
            <!-- DocumentType, Version, ConformanceLevel declared the same way -->
          </rdf:Seq>
        </pdfaSchema:property>
      </rdf:li>
    </rdf:Bag>
  </pdfaExtension:schemas>
</rdf:Description>

URI imenskog prostora i prefiks nisu fiksni nizovi. Slede profil. Factur-X dokument koristi urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0# sa prefiksom fx, dok ZUGFeRD 2.0 datoteka odabrana putem zugferd-invoice.xml razresava se na drugaciji URI pod vlastitim imenom seme. Prosirena sema mora deklarisati isti URI imenskog prostora koji blok svojstava zapravo koristi, ili validator i dalje ne moze povezati dvoje. PDFlibPas izvodi obe vrednosti iz naziva datoteke i verzije koje prosledjujete, pa se deklaracija i blok svojstava uvek slazu

Kako helper zapisuje oba dela zajedno

U PDFlibPas-u ne sastavljate taj XML rucno. Postavite dokument u PDF/A-3 nacin i pozovete jednu metodu. Prva stvar koju treba resiti je zastavica konformnosti, jer Factur-X zahteva PDF/A-3. Pozivanje SetPDFAMode(7) bira nivo PDF/A-3u, koji postavlja pdfaid:part na 3 i pdfaid:conformance na U u semi identifikacije. XMP paket sada nosi ispravan deo i konformnost pre dodavanja metapodataka fakture

var
  FileID: Integer;
begin
  PDF.SetPDFAMode(7);            // PDF/A-3u: pdfaid:part=3, conformance=U
  PDF.NewDocument;
  // draw the human-readable invoice page here

  FileID := PDF.AddFacturXAssociatedFileFromString(
    InvoiceXML,                  // raw UTF-8 XML bytes
    'EN16931',                   // ConformanceLevel
    'factur-x.xml',              // embedded file name
    'Factur-X invoice XML',      // /Desc text
    'Alternative',               // /AFRelationship
    '1.0',                       // profile version
    '');                         // optional country code
  if FileID = 0 then
    Exit;                        // not PDF/A-3, or XML/profile mismatch

  PDF.SaveToFile('factur-x.pdf');
end;

Jedan poziv na AddFacturXAssociatedFileFromString obavlja posao koji je nedostajao neuspeloj datoteci. Ugradjuje XML kao PDF/A-3 pridrzenu datoteku sa vezom koju ste imenovali, i zapisuje cetiri fx svojstva zajedno sa imenom seme, URI imenskog prostora i prefiksom za odabrani profil. Kada se dokument sacuva, interni korak nazvan ApplyFacturXMetadata ubacuje i blok svojstava i odgovarajucu pdfaExtension:schemas deklaraciju u XMP paket, tako da prilagodjena svojstva stizu vec opisana. Metoda vraca 0 ako dokument nije u PDF/A-3 nacinu ili ako XML ne odgovara deklarisanom profilu, sto je ista zastita koja sprecava malformiranu fakturu da dodje do datoteke

Slepa tacka koju provera kontejnera ne moze videti

Ovo je deo koji treba jasno navesti, jer je razlog zasto se greska skriva. ValidateFacturXInvoice proverava kontejner. Potvradjuje da katalog ima /AF unos, da je stablo naziva EmbeddedFiles prisutno, da XML fakture postoji, da naziv ugradene datoteke odgovara profilu, da se ID smernice u XML-u slaze sa nivoom konformnosti, i da je /AFRelationship jedan koji PDF/A-3 dozvoljava. To su prave provere i hvataju prave nedostatke. GetFacturXValidationIssues ih prijavljuje po imenu, sa identifikatorima kao sto su MissingCatalogAF, NotPDFA3, ConformanceGuidelineMismatch, InvalidAFRelationship i InvalidFileNameProfile

Ono sto ne proverava je da li je XMP prosirena sema prisutna i ispravna. Datoteka ciji kontejner je besprekoran ali cija fx svojstva su nedeklarisana prolazi svaku proveru problema i vraca 1, jer nista na toj listi ne ispituje blok pdfaExtension:schemas. To je tacno razlog zasto rucno izgradjena faktura, ili ona proizvedena sistemom koji je zapisao blok svojstava bez deklaracije, moze proci kroz ugradeni validator i ipak ne proci veraPDF na klauzuli 6.6.2.3.1. Validator kontejnera i validator PDF/A metapodataka odgovaraju na razlicita pitanja, a samo potpuni PDF/A proverac odgovara na drugo

Citanje problema kako biste znali koji sloj je pukao

Buduci da dva sloja ne uspevaju nezavisno, ispravna dijagnosticka navika je prvo citati probleme kontejnera i tretirati cisti rezultat kao izjavu samo o kontejneru, nikad o PDF/A metapodacima. Pokrenite ugradenu validaciju, prikupite listu problema i delujte na nju pre nego sto posegnete za spoljnim alatom

var
  Issues: WideString;
begin
  if PDF.ValidateFacturXInvoice = 0 then
  begin
    Issues := PDF.GetFacturXValidationIssues('|');
    // container-level identifiers, for example:
    //   MissingCatalogAF, NotPDFA3, MissingEmbeddedFilesNameTree,
    //   ConformanceGuidelineMismatch, InvalidAFRelationship
    WriteLn('Container issues: ', Issues);
  end
  else
    WriteLn('Container OK; verify XMP extension schema with a PDF/A checker.');
end;

Kada taj poziv vrati ime problema, greska je u kontejneru i poruka vam govori koji deo. Kada vrati cisto a veraPDF i dalje odbija datoteku, greska je gotovo uvek XMP prosirena sema, a ispravak je pustiti AddFacturXAssociatedFileFromString da zapisuje metapodatke umesto da sami konstruisete blok svojstava. Odvajanje dva pitanja u vasem umu je ono sto pretvara zbunjujuce odbijanje u jednolinijsku dijagnozu: problemi kontejnera pojavljuju se kroz listu problema, problemi deklaracije seme pojavljuju se samo kroz PDF/A validator, a zbrkavanje oba je ono sto pusta gresku da se skriva

Sira slika PDF/A i PDF/UA konformnosti, ukljucujuci kako pokrenuti predlet prolaz pre nego sto datoteka napusti vas build, obradjena je u PDF/A i PDF/UA predlet pregledu. Ako vasa faktura takodje mora biti pristupacna, stablo strukture od kojeg zavise PDF/A-3a i oznaceni PDF je tema clanka o pristupacnosti oznacenog PDF-a. Upravljanje prosirenim semama opisano ovde isporucuje se kao deo PDFlibPas Delphi PDF Library zajedno sa podrzkom profila Factur-X, ZUGFeRD i XRechnung dokumentovanom u ovom blogu