Bir Factur-X veya ZUGFeRD faturası, tek (one) bir dosya adı (filename) taşıyan (wearing) iki (two) belgedir (documents). Dış (outer) belge (document), bir arşiv okuyucusunun (archival reader) önümüzdeki on yıl (ten years) boyunca kabul etmesi (accept) gereken bir PDF/A-3 kapsayıcısıdır (container). İç (inner) belge, bir alıcının (buyer's) muhasebe sisteminin (accounting system) EN 16931'e göre ayrıştırması (parse) gereken bir XML faturasıdır. Bozuk faturaları üretime (into production) gönderen (ships) hata, ilkini doğru yapmanın (getting the first one right) ikincisini bedavaya (for free) getirdiğine (gets) inanmaktır. Öyle değildir (It does not). Bir dosya (file) kusursuz (flawless) bir PDF/A-3 olabilir ve yine de (still) hiçbir (no) vergi dairesinin (tax authority) kabul etmeyeceği (will accept) XML taşıyabilir (carry) ve arşivsel doğrulamada (archival validation) başarısız olan bir kapsayıcının (container) içinde (inside) ders kitabı (textbook) niteliğinde EN 16931 XML'i taşıyabilir. İki (two) katman (layers), birbirleri hakkında hiçbir şey bilmeyen iki (two) farklı araç (tools) tarafından doğrulanır ve gerçek bir boru hattının (pipeline) her ikisini de (both) tatmin etmesi (satisfy) gerekir
İki (two) doğrulayıcı (validators), iki farklı soru (questions)
veraPDF, PDF/A için referans (reference) uygulamasıdır (implementation). Onu bir faturaya yöneltin (Point it) ve tek (one) bir soruyu (question) yanıtlasın: bu uyumlu (conformant) bir PDF/A-3 dosyası mı. ISO 19005-3'ün önemsediği (cares about) şeyleri (things) kontrol eder. Her (every) yazı tipi (font) gömülü (embedded) mü. Bir OutputIntent var mı. XMP meta verileri (metadata) doğru (right) parçayı (part) ve uygunluk düzeyini (conformance level) beyan ediyor (declare) mu. Bir e-fatura için ayrıca (also) PDF/A-3'ün gerektirdiği ilişkili dosya (associated-file) tesisatını (plumbing) da kontrol eder, çünkü (because) XML, bir /AFRelationship ve belge kataloğunun (document catalog's) /AF dizisinde bir giriş (entry) ile (with) gömülü (embedded) bir dosya (file) olarak ilerler. veraPDF fatura toplamının (invoice total) toplanıp toplanmadığı (adds up) hakkında hiçbir şey söylemez, çünkü bu onun (its) yetki alanında (remit) değildir
Mustang, Mustangproject'in açık kaynaklı (open-source) doğrulayıcısıdır (validator). Ortogonal soruyu sorar (asks): gömülü (embedded) XML geçerli (valid) bir fatura mı. XML'i bildirilen (declared) profil (profile) için şemaya (schema) karşı (against) çalıştırır ve ardından (then) EN 16931 iş kurallarını (business rules) ve üstüne katmanlanmış (layered on top) ülkeye özgü kural kümelerini (rule sets), XRechnung'un CIUS'u da aralarında olmak üzere, uygular. Toplamlar (totals) gerektirdiğinde bir satıcı KDV tanımlayıcısının (seller VAT identifier) mevcut olup olmadığını, indirim (allowance) ve masraf (charge) tutarlarının belge toplamı (document total) ile (against) uzlaşıp uzlaşmadığını (reconcile), XML'deki profil URN'sinin dosyanın (file) iddia ettiği (claims) şeyle eşleşip eşleşmediğini (matches) kontrol eder. Mustang, çevreleyen PDF'in (surrounding PDF) yazı tiplerini (fonts) gömüp gömmediğiyle (embeds) ilgilenmez (does not care), çünkü bu veraPDF'in işidir
Her iki araç (tool) da (Neither) diğerinin (the other) bir üst kümesi (superset) değildir. veraPDF, anlamsız (nonsense) XML'in etrafındaki (around) yapısal olarak (structurally) mükemmel (perfect) bir kapsayıcıyı geçirir (passes). Mustang, eksik (missing) bir OutputIntent'e sahip (with) bir kapsayıcıya sarılmış mükemmel (perfect) XML'i geçirir. Her biri tam olarak (exactly) diğerinin kör (blind) olduğu (to) hata sınıfını (class of defect) yakalar, ki ciddi bir doğrulama test ortamının (harness) her ikisini de (both) çalıştırmasının (runs) ve bir dosyayı yalnızca her ikisi de aynı fikirde olduğunda (agree) gönderilebilir (shippable) olarak ele almasının (treats) tüm nedeni budur (is the entire reason)
Doğrulama matrisi (The validation matrix)
Kütüphanenin (library) her iki (both) kapıdan (gates) da (survive) sağ (survive) çıkan (survive) dosyalar ürettiğini kanıtlamak için, test ortamı (harness) bir matris oluşturur. Altı (Six) fatura profili (invoice profiles), bir Avrupa (European) boru hattının (pipeline) uygulamada karşılaştığı aralığı (range) kapsar: Factur-X EN 16931, Factur-X BASIC, Factur-X EXTENDED France B2B varyantı (variant), XRechnung 3.0, ZUGFeRD 1.0 COMFORT ve ZUGFeRD 2.0 BASIC. Her (Each) profil, iki (two) PDF/A alt uygunluk seviyesine (sub-conformance levels), 3b ve 3u'ya karşı oluşturulur (is generated), çünkü seviye B ve seviye U gereksinimleri (requirements) Unicode eşlemesinde farklılık gösterir (diverge) ve birini geçen bir dosya diğerinde başarısız olabilir (can fail). İki (two) seviye (levels) çarpı altı profil on iki (twelve) dosya demektir, bunların (them) her biri (every one), GUI örneğinin gönderdiği aynı (same) kod yolu (code path) tarafından gözetimsiz (headless) olarak oluşturulur, böylece test altındaki eserler (artifacts) test için elle (hand-tuned) ayarlanmaz (are not)
Üretici (generator) on iki dosyanın tamamını (all twelve) yazar ve bir betik (script) her birini her iki doğrulayıcıya besler. İlk tam (full) çalıştırmada (run) veraPDF on iki dosyanın tamamından geçti. Kapsayıcı (container) tesisatı tüm panoda (across the board) doğruydu: ilişkili dosyalar kaydedildi, XMP uygunluğu beyan edildi (declared), çıktı niyetleri (output intents) yerindeydi (in place). Mustang sekiz (eight) tanesini geçirdi. Dört (Four) fatura, iş kuralı doğrulayıcısının (business-rule validator) reddettiği (rejected) XML taşıyan (carrying) yapısal olarak (structurally) geçerli (valid) PDF/A-3 dosyalarıydı, ki bu tam da (precisely) iki araçlı yaklaşımın yüzeye çıkarmak için var olduğu ayrımdır (split). Eğer (Had) test ortamı yalnızca veraPDF'e güvenseydi (trusted), bu (those) dört dosya bitmiş (finished) gibi görünecekti
Boşluğu (gap) kapatan (closed) iki (two) düzeltme (fixes)
Dört Mustang arızası (failures) iki (two) farklı (distinct) nedenden (causes) kaynaklanıyordu (came from) ve her (each) birine (for) yönelik düzeltme (fix), siz bu profilleri kendiniz (yourself) oluşturmadan (generate) önce (before) bilmeye değer bir ayrıntıdır (detail)
İlki (first) Factur-X EXTENDED France B2B profiliydi. Orijinal üretici, dahili (internal) bir etiketi (label) uygunluk düzeyi olarak ve dahili bir URN'yi kılavuz (guideline) olarak geçirdi (passed) ve Mustang dosyayı geçersiz (invalid) bir uygunluk (conformance) değeri (value) hatası ve ardından (followed by) desteklenmeyen (unsupported) bir profil (profile) türü hatasıyla reddetti. Bunun nedeni (The reason is that), XMP fx:ConformanceLevel alanının kendi (your own) profil isimlendirmeniz (naming) için serbest metin (free-text) bir yuva (slot) olmamasıdır. Factur-X, bunun (it) için tam olarak beş (five) standart değer (values) tanımlar: MINIMUM, BASIC WL, BASIC, EN 16931 ve EXTENDED. Fransa'ya (France-specific) özgü bir B2B faturası, XMP meta verileri söz konusu olduğunda (as far as is concerned) hala (still) EXTENDED profilli bir belgedir (document). Faturanın (invoice) Fransız (French) karakteri, altıncı (sixth) bir uygunluk (conformance) değeri (value) icat edilerek (inventing) ifade edilmez (is not expressed). Ülke (country) kodu olan FR ile ve EN 16931'e uygun (conformant) bir CIUS'u işaretleyen (marks) urn:cen.eu:en16931:2017#conformant# önekini (prefix) taşıması gereken (has to) XML içindeki (inside the) kılavuz tanımlayıcısı (guideline identifier) ile ifade edilir. Standart (standard) EXTENDED değerini (value) ülke (country) kodu olarak FR ve doğru (correct) kılavuz (guideline) URN'si ile (with) iletmek (Passing), dosyayı uygun (conformant) hale getirdi (made)
Kitaplık (library) API'sinde bu, (that is) uygunluk (conformance), ülke (country) ve kılavuzun hizalandığı (aligned) AddFacturXAssociatedFileFromString fonksiyonuna (to) yapılan bir çağrıdır (call). Uygunluk (conformance) düzeyi (level) argümanı (argument) standart belirteci (token) taşır (carries), ülke kodu (country code) argümanı FR taşır ve kılavuz (guideline) URN'si geçirdiğiniz (pass in) XML baytlarında (bytes) yaşar (lives)
var
FileID: Integer;
begin
PDF.SetPDFAMode(5); // PDF/A-3b
PDF.NewDocument;
// ... draw the human-readable invoice page ...
// ExtendedXML carries an EN 16931 guideline URN of the form
// urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended
FileID := PDF.AddFacturXAssociatedFileFromString(
ExtendedXML,
'EXTENDED', // standard fx:ConformanceLevel, not an internal label
'factur-x.xml',
'Factur-X EXTENDED invoice',
'Alternative', // /AFRelationship
'1.0',
'FR'); // France B2B marked by country code, not by conformance
if FileID = 0 then
raise Exception.Create('Factur-X attachment rejected');
PDF.SaveToFile('02_Factur-X-EXTENDED-FR_PDFA-3b.pdf');
end;
İkinci neden (The second cause) ZUGFeRD 1.0 COMFORT profiliydi ve (and it) meta verilerle hiçbir ilgisi yoktu (had nothing to do with). ZUGFeRD 1.0, kardinalite (cardinality) konusunda düz yazı (prose) özetlerinin önerdiğinden (suggest) daha katı (stricter) olan :1p0 XSD'ye karşı doğrulanır (is validated against). XSD, başlık (header) ödeme (settlement) toplamının (summation), yani ram:SpecifiedTradeSettlementMonetarySummation'ın, her biri (each) tam olarak (exactly) bir kez (once) olacak şekilde ram:ChargeTotalAmount ve ram:AllowanceTotalAmount içermesini gerektirir. Üretilen XML her ikisini de atlamıştı (omitted both), bu yüzden Mustang öğelerin tam olarak (exactly) bir kez (one time) geçmesi (occur) gerektiğini (must) bildirdi (reported). Şema (schema) minOccurs değerinin bir olduğunu söylediğinde (says) bunlar (These) isteğe bağlı (optional) değildir (are not). Hiç masraf (charges) veya indirim (allowances) olmadığında 0.00 değeriyle, tam olarak (immediately after) ram:LineTotalAmount'dan sonra XSD sırasına (sequence order) göre her ikisini de yaymak (Emitting), şemayı tatmin etti (satisfied). Bir sıfır (zero) mevcut (present) bir öğedir; eksik (absent) bir öğe bir şema ihlalidir (violation). Yerinde (in place) olan (With) bu iki (two) düzeltmeyle (fixes) birlikte matris, veraPDF üzerinde on ikide on iki kalırken (staying) Mustang üzerinde on ikide on ikiye çıktı (went to)
Geçersizi (invalid) geçerli (valid) yapan (flip) XRechnung alanları (fields)
XRechnung kendi (its own) notunu hak eder çünkü (because) Alman CIUS'u, temel EN 16931 kümesinde (set) bulunmayan (absent from) iş kuralları ekler (adds) ve (and they) bir bakışta (at a glance) belgede hiçbir sorun yokmuş (nothing is wrong) gibi (like) görünen (look) şekillerde (ways) başarısız olurlar (fail). Bunlardan ikisi (Two of them) elektronik adreslerle (addresses) ilgilidir. BT-34 satıcının elektronik adresidir ve BT-49 alıcının elektronik adresidir; bir Alman (German) kamu sektörü (public-sector) portalının faturayı teslim etmek (deliver) ve onaylamak (acknowledge) için (to) kullandığı yönlendirme uç noktaları (routing endpoints). Temel (base) EN 16931 modeli (model) bunları (them) isteğe bağlı (optional) olarak (as) ele alır (treats). XRechnung öyle yapmaz (does not). Herhangi birini (either) atlarsanız (Omit) fatura iyi biçimlendirilmiş (well-formed), şema açısından geçerli (schema-valid) olur ve reddedilir (rejected)
Üçüncüsü, satıcının iletişim telefon numarasının (contact telephone number) bulunmasını gerektiren BR-DE-6 kuralıdır. Veriden (data) ziyade (rather than) sunum (presentation) gibi (like) hissettirdiği (feels) için bir geliştiricinin (developer) düşürdüğü (drops) türden bir alandır ve yokluğu (absence), açıkça (obviously) eksik (missing) olan herhangi bir şeyden (anything) ziyade (rather than) satıcı (seller) iletişim (contact) grubuna (group) işaret eden (points at) bir doğrulama (validation) hatası (failure) üretir (produces). BT-34, BT-49 ve satıcının telefon numarasını (seller phone number) sağlamak (Supplying), bir XRechnung dosyasını Mustang altında (under) geçersizden (from invalid) geçerliye (to valid) taşıyan şeydir (moves) ve (and none of it) veraPDF'in gördüğü hiçbir şeyi (anything) değiştirmez (changes), çünkü her (all) üçü de (three) XML içinde (in the) yaşar (live)
Kütüphane (library) çıktısını (output) bir doğrulayıcıya (validator) bağlama (Wiring)
Test ortamının (harness) arkasındaki (behind) mimari nokta (point), herhangi bir (any) iş sistemine (business system) genellenebilir (generalizes to). PDF kütüphanesi uyumlu (conformant) bir kapsayıcı (container) yazar ve XML'i gömer (embeds). EN 16931 iş kuralı otoritesi (authority) olmaya çalışmaz ve çalışmamalıdır (should not). Kütüphanedeki (in the library) ValidateFacturXInvoice, kapsayıcı tutarlılığını (consistency), yani katalog (catalog) /AF dizisinin (array), gömülü dosya (embedded-files) isim ağacının (name tree), XMP DocumentFileName'in, profilin (profile), kılavuzun (guideline) ve /AFRelationship'in hepsinin (all) uyuştuğunu (agree) kontrol eder (checks), ancak vergi (tax) kodlarını doğrulamaz (validate) veya tutarları (amounts) uzlaştırmaz (reconcile). Doğru (right) iş bölümü (division of labor), iş sisteminin XML'i çıkarması (extract) ve onu (it) tıpkı (exactly as) test ortamının (harness) Mustang'e verdiği gibi (hands it) özel (dedicated) bir fatura doğrulayıcısına vermesidir (hand)
Dosyayı (file) geri okumak (Reading back), size gerçekte ne (what) yazıldığını söyler (tells you). DetectFacturXInvoice bir faturanın tanınıp (recognized) tanınmadığını bildirir (reports) ve GetFacturXInvoiceInfo meta veri alanlarını (fields) etikete (tag) göre okur: etiket 1 gömülü dosya adıdır (embedded file name), etiket 2 XMP DocumentFileName'dir, etiket 5 uygunluk düzeyi (conformance level), etiket 6 kılavuz tanımlayıcısı (guideline identifier) ve etiket 7 /AFRelationship'dir. Geri okuduğunuz uygunluk düzeyinin dahili bir etiket değil standart belirteç olduğunu doğrulamak (Confirming), bir dosya (file) derlemenizden (build) ayrılmadan (leaves) önce (before) EXTENDED hatasını (mistake) yakalamanın (catch) en ucuz (cheapest) yoludur (way)
function ExtractAndInspect(const PdfPath: string): AnsiString;
var
Profile, Guideline: WideString;
begin
Result := '';
PDF.LoadFromFile(PdfPath);
if PDF.DetectFacturXInvoice = 1 then
begin
Profile := PDF.GetFacturXInvoiceInfo(5); // fx:ConformanceLevel
Guideline := PDF.GetFacturXInvoiceInfo(6); // XML guideline ID
Writeln('Profile: ', Profile);
Writeln('Guideline: ', Guideline);
// Hand the raw XML to a dedicated EN 16931 / Mustang validator.
Result := PDF.ExtractFacturXXMLToString;
end;
end;
ExtractFacturXXMLToString, bir dosyaya yazmaya (write) veya bir doğrulayıcı (validator) işlemine (process) akıtmaya (stream into) hazır (ready) bir şekilde, ham (raw) XML baytlarını bir AnsiString olarak döndürür (returns). Test (test) ortamında (harness) bu hedef, veraPDF'in de aynı (same) geçişte (pass) aynı (same) dosya (file) üzerinde (over) çalıştırıldığı (run), komut satırı (command-line) jar dosyası aracılığıyla (through) çağrılan (invoked) Mustang'dir. Kablolama (wiring) küçüktür (is small): bir konsol (console) üreticisi (generator), EInvoiceValidation.dpr, örnekteki (sample) paylaşılan (shared) fatura modelini (model) kullanarak on iki (twelve) dosyayı (files) yazar ve (and) bir betik (script), run-validation.ps1, her iki doğrulayıcıyı (validators) çıktı (output) dizini (directory) üzerinde yönlendirir (drives) ve bir geçme (pass) ve (and) kalma (fail) tablosu (table) yazdırır (prints). Aynı (same) iki adımlı (two-step) şekil, kütüphane ile (with) üretme (generate) ve harici (external) doğrulayıcılarla doğrulama (verify), faturanın oluşturulmasındaki her değişiklikle birlikte kesintisiz bir entegrasyon işinin (a continuous-integration job) yürütmesi gereken (should run on) şeydir (is what), çünkü bir dosyanın her iki (both) katmanı da (layers) karşıladığını (satisfies) bilmenin tek (only) yolu (way) her iki (both) araca (tools) da (ask) sormaktır
Boru (pipeline) hattınızın (your) imzalamadan (signing) önce (before) kapsayıcıyı (container) sertifikalandırması (certify) da (also) gerekiyorsa, bu (this) işin (work) uçuş öncesi (preflight) tarafı Delphi'deki PDF/A ve PDF/UA uçuş öncesi (preflight) incelememizde ele alınmıştır ve (and the) daha (broader) geniş (broader) önce (then) sertifikalandır sonra (certify-then) imzala (sign) akışı (flow) uyumluluk (compliance) ve (and) imzalama (signing) çalışma masasında (workbench) açıklanmıştır. Her ikisi de, burada kullanılan (used here) PDF/A, ilişkili dosya (associated-file) ve meta veri (metadata) API'lerinin yanı sıra, Delphi ve C++Builder için Delphi PDF Library'nin bir parçası (part) olarak gönderilen aynı üretim yolu (generation path) üzerine inşa edilir (build on)