Merge pull request #1083 from truearken/feature-pdf-langs

PDF Visualizations in English and French
This commit is contained in:
Jochen Staerk
2026-04-09 11:22:16 +02:00
committed by GitHub
5 changed files with 633 additions and 315 deletions

View File

@@ -217,7 +217,7 @@ public class ZUGFeRDVisualizer {
}
}
protected String toFOP(String xmlFilename)
protected String toFOP(String xmlFilename, Language lang)
throws IOException, TransformerException, ParserConfigurationException {
EStandard theStandard;
try (FileInputStream fis = new FileInputStream(xmlFilename)) {
@@ -225,11 +225,11 @@ public class ZUGFeRDVisualizer {
}
try (FileInputStream fis = new FileInputStream(xmlFilename)) {
return toFOP(fis, theStandard);
return toFOP(fis, theStandard, lang);
}
}
protected String toFOP(InputStream is, EStandard theStandard)
protected String toFOP(InputStream is, EStandard theStandard, Language lang)
throws TransformerException, IOException {
try {
@@ -256,12 +256,16 @@ public class ZUGFeRDVisualizer {
Optional<InputStream> in = copyStream(iaos);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (in.isPresent()) {
applyXSLTToPDF(in.get(), baos);
applyXSLTToPDF(in.get(), baos, lang);
}
return baos.toString(StandardCharsets.UTF_8);
}
public void toPDF(String xmlFilename, String pdfFilename) {
toPDF(xmlFilename, pdfFilename, Language.DE);
}
public void toPDF(String xmlFilename, String pdfFilename, Language lang) {
// the writing part
File XMLinputFile = new File(xmlFilename);
@@ -272,7 +276,7 @@ public class ZUGFeRDVisualizer {
out from git with arbitrary options (which may include CSRF changes)
*/
try {
fopInput = this.toFOP(XMLinputFile.getAbsolutePath());
fopInput = this.toFOP(XMLinputFile.getAbsolutePath(), lang);
} catch (TransformerException | IOException | ParserConfigurationException e) {
LOGGER.error("Failed to apply FOP", e);
}
@@ -286,8 +290,12 @@ public class ZUGFeRDVisualizer {
return null;
}, (OutputStream out) -> {});
}
public byte[] toPDF(String xmlContent) {
return toPDF(xmlContent, Language.DE);
}
public byte[] toPDF(String xmlContent, Language lang) {
String fopInput = null;
@@ -299,7 +307,7 @@ public class ZUGFeRDVisualizer {
EStandard theStandard = findOutStandardFromRootNode(fis);
fis = new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8));//rewind :-(
fopInput = toFOP(fis, theStandard);
fopInput = toFOP(fis, theStandard, lang);
} catch (TransformerException | IOException | ParserConfigurationException e) {
LOGGER.error("Failed to apply FOP", e);
}
@@ -435,9 +443,10 @@ public class ZUGFeRDVisualizer {
xmlFile.close();
}
protected void applyXSLTToPDF(final InputStream xmlFile, final OutputStream PDFOutstream)
protected void applyXSLTToPDF(final InputStream xmlFile, final OutputStream PDFOutstream, Language lang)
throws TransformerException, IOException {
Transformer transformer = mXsltPDFTemplate.newTransformer();
transformer.setParameter("lang", lang.name().toLowerCase());
transformer.transform(new StreamSource(xmlFile), new StreamResult(PDFOutstream));
xmlFile.close();

View File

@@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<entry key="xr:Buyer_reference" id="BT-10">Référence acheteur</entry>
<entry key="xr:Buyer_name" id="BT-44">Nom</entry>
<entry key="xr:Buyer_address_line_1" id="BT-50">Adresse ligne 1</entry>
<entry key="xr:Buyer_address_line_2" id="BT-51">Adresse ligne 2</entry>
<entry key="xr:Buyer_address_line_3" id="BT-163">Adresse ligne 3</entry>
<entry key="xr:Buyer_post_code" id="BT-53">Code postal</entry>
<entry key="xr:Buyer_city" id="BT-52">Ville</entry>
<entry key="xr:Buyer_country_code" id="BT-55">Code pays</entry>
<entry key="xr:Buyer_identifier" id="BT-46">Identifiant</entry>
<entry key="xr:Buyer_identifier/@scheme_identifier" id="BT-46_scheme">Schéma de l'identifiant</entry>
<entry key="xr:Buyer_contact_point" id="BT-56">Nom</entry>
<entry key="xr:Buyer_contact_telephone_number" id="BT-57">Téléphone</entry>
<entry key="xr:Buyer_contact_email_address" id="BT-58">Adresse e-mail</entry>
<entry key="xr:Seller_name" id="BT-27">Raison sociale</entry>
<entry key="xr:Seller_address_line_1" id="BT-35">Adresse ligne 1</entry>
<entry key="xr:Seller_address_line_2" id="BT-36">Adresse ligne 2</entry>
<entry key="xr:Seller_address_line_3" id="BT-162">Adresse ligne 3</entry>
<entry key="xr:Seller_post_code" id="BT-38">Code postal</entry>
<entry key="xr:Seller_city" id="BT-37">Ville</entry>
<entry key="xr:Seller_country_subdivision" id="BT-39">Région</entry>
<entry key="xr:Seller_country_code" id="BT-40">Code pays</entry>
<entry key="xr:Seller_identifier" id="BT-29">Identifiant</entry>
<entry key="xr:Seller_identifier/@scheme_identifier" id="BT-29_scheme">Schéma de l'identifiant</entry>
<entry key="xr:Seller_contact_point" id="BT-41">Nom</entry>
<entry key="xr:Seller_contact_telephone_number" id="BT-42">Téléphone</entry>
<entry key="xr:Seller_contact_email_address" id="BT-43">Adresse e-mail</entry>
<entry key="xr:Invoice_number" id="BT-1">Numéro de facture</entry>
<entry key="xr:Invoice_issue_date" id="BT-2">Date de facture</entry>
<entry key="xr:Invoice_type_code" id="BT-3">Type de facture</entry>
<entry key="xr:Invoice_currency_code" id="BT-5">Devise</entry>
<entry key="xr:Project_reference" id="BT-11">Numéro de projet</entry>
<entry key="xr:Contract_reference" id="BT-12">Numéro de contrat</entry>
<entry key="xr:Purchase_order_reference" id="BT-13">Numéro de commande</entry>
<entry key="xr:Sales_order_reference" id="BT-14">Référence de commande client</entry>
<!-- Be aware that these are for the whole invoice -->
<entry key="xr:Invoicing_period_start_date" id="BT-73">Du</entry>
<entry key="xr:Invoicing_period_end_date" id="BT-74">Au</entry>
<entry key="xr:Preceding_Invoice_reference" id="BT-25">Numéro de facture</entry>
<entry key="xr:Preceding_Invoice_issue_date" id="BT-26">Date de facture</entry>
<entry key="xr:Sum_of_Invoice_line_net_amount" id="BT-106">Total des lignes</entry>
<entry key="xr:Sum_of_allowances_on_document_level" id="BT-107">Total des remises</entry>
<entry key="xr:Sum_of_charges_on_document_level" id="BT-108">Total des frais</entry>
<entry key="xr:Invoice_total_amount_without_VAT" id="BT-109">Total HT</entry>
<entry key="xr:Invoice_total_VAT_amount" id="BT-110">Total TVA</entry>
<entry key="xr:Invoice_total_VAT_amount_in_accounting_currency" id="BT-111">Total TVA en devise comptable</entry>
<entry key="xr:Invoice_total_amount_with_VAT" id="BT-112">Total TTC</entry>
<entry key="xr:Paid_amount" id="BT-113">Montant payé</entry>
<entry key="xr:Rounding_amount" id="BT-114">Montant d'arrondi</entry>
<entry key="xr:Amount_due_for_payment" id="BT-115">Montant dû</entry>
<entry key="xr:VAT_category_code" id="BT-118">Catégorie de TVA</entry>
<entry key="xr:VAT_category_taxable_amount" id="BT-116">Total</entry>
<entry key="xr:VAT_category_rate" id="BT-119">Taux de TVA</entry>
<entry key="xr:VAT_category_tax_amount" id="BT-117">Montant de TVA</entry>
<entry key="xr:VAT_exemption_reason_text" id="BT-120">Motif d'exonération</entry>
<entry key="xr:VAT_exemption_reason_code" id="BT-121">Code du motif d'exonération</entry>
<!-- Remises -->
<entry key="xr:Document_level_allowance_VAT_category_code" id="BT-95">Catégorie de TVA de la remise</entry>
<entry key="xr:Document_level_allowance_base_amount" id="BT-93">Montant de base</entry>
<entry key="xr:Document_level_allowance_percentage" id="BT-94">Pourcentage</entry>
<entry key="xr:Document_level_allowance_amount" id="BT-92">Remise</entry>
<entry key="xr:Document_level_allowance_VAT_rate" id="BT-96">Taux de TVA de la remise</entry>
<entry key="xr:Document_level_allowance_reason" id="BT-97">Motif de la remise</entry>
<entry key="xr:Document_level_allowance_reason_code" id="BT-98">Code du motif de la remise</entry>
<!-- Frais -->
<entry key="xr:Document_level_charge_VAT_category_code" id="BT-102">Catégorie de TVA des frais</entry>
<entry key="xr:Document_level_charge_base_amount" id="BT-100">Montant de base</entry>
<entry key="xr:Document_level_charge_percentage" id="BT-101">Pourcentage</entry>
<entry key="xr:Document_level_charge_amount" id="BT-99">Frais</entry>
<entry key="xr:Document_level_charge_VAT_rate" id="BT-103">Taux de TVA des frais</entry>
<entry key="xr:Document_level_charge_reason" id="BT-104">Motif des frais</entry>
<entry key="xr:Document_level_charge_reason_code" id="BT-105">Code du motif des frais</entry>
<entry key="xr:Payment_terms" id="BT-20">Escompte ; autres conditions de paiement</entry>
<entry key="xr:Payment_due_date" id="BT-9">Date d'échéance</entry>
<entry key="xr:Payment_means_type_code" id="BT-81">Code du moyen de paiement</entry>
<entry key="xr:Payment_means_text" id="BT-82">Moyen de paiement</entry>
<entry key="xr:Remittance_information" id="BT-83">Référence de paiement</entry>
<entry key="xr:Payment_card_primary_account_number" id="BT-87">Numéro de carte</entry>
<entry key="xr:Payment_card_holder_name" id="BT-88">Titulaire de la carte</entry>
<!-- BG-19 Direct Debit -->
<entry key="xr:Mandate_reference_identifier" id="BT-89">Référence du mandat</entry>
<entry key="xr:Debited_account_identifier" id="BT-91">IBAN</entry>
<entry key="xr:Bank_assigned_creditor_identifier" id="BT-90">Identifiant créancier</entry>
<!-- BG-17 Credit Transfer-->
<entry key="xr:Payment_account_name" id="BT-85">Titulaire du compte</entry>
<entry key="xr:Payment_account_identifier" id="BT-84">IBAN</entry>
<entry key="xr:Payment_service_provider_identifier" id="BT-86">BIC</entry>
<entry key="xr:Invoice_note_subject_code" id="BT-21">Objet</entry>
<entry key="xr:Invoice_note" id="BT-22">Remarque</entry>
<!-- BG-4 Seller and others -->
<entry key="xr:Seller_trading_name" id="BT-28">Nom commercial</entry>
<entry key="xr:Seller_electronic_address" id="BT-34">Adresse électronique</entry>
<entry key="xr:Seller_electronic_address/@scheme_identifier" id="BT-34_scheme">Schéma de l'adresse électronique</entry>
<entry key="xr:Seller_legal_registration_identifier" id="BT-30">Numéro SIRET/SIREN</entry>
<entry key="xr:Seller_legal_registration_identifier/@scheme_identifier" id="BT-30_scheme">Schéma du numéro d'enregistrement</entry>
<entry key="xr:Seller_VAT_identifier" id="BT-31">Numéro de TVA intracommunautaire</entry>
<entry key="xr:Seller_tax_registration_identifier" id="BT-32">Numéro fiscal</entry>
<entry key="xr:Seller_additional_legal_information" id="BT-33">Informations juridiques complémentaires</entry>
<entry key="xr:VAT_accounting_currency_code" id="BT-6">Code devise de la TVA</entry>
<!-- BG 12 and 11 Tax Representative party -->
<entry key="xr:Seller_tax_representative_name" id="BT-62">Nom</entry>
<entry key="xr:Tax_representative_address_line_1" id="BT-64">Adresse ligne 1</entry>
<entry key="xr:Tax_representative_address_line_2" id="BT-65">Adresse ligne 2</entry>
<entry key="xr:Tax_representative_address_line_3" id="BT-164">Adresse ligne 3</entry>
<entry key="xr:Tax_representative_post_code" id="BT-67">Code postal</entry>
<entry key="xr:Tax_representative_city" id="BT-66">Ville</entry>
<entry key="xr:Tax_representative_country_subdivision" id="BT-68">Région</entry>
<entry key="xr:Tax_representative_country_code" id="BT-69">Code pays</entry>
<entry key="xr:Seller_tax_representative_VAT_identifier" id="BT-63">Numéro de TVA intracommunautaire</entry>
<!-- Additional buyer information from different bgs -->
<entry key="xr:Buyer_trading_name" id="BT-45">Nom commercial</entry>
<entry key="xr:Buyer_country_subdivision" id="BT-54">Région</entry>
<entry key="xr:Buyer_electronic_address" id="BT-49">Adresse électronique</entry>
<entry key="xr:Buyer_electronic_address/@scheme_identifier" id="BT-49_scheme">Schéma de l'adresse électronique</entry>
<entry key="xr:Buyer_legal_registration_identifier" id="BT-47">Numéro SIRET/SIREN</entry>
<entry key="xr:Buyer_legal_registration_identifier/@scheme_identifier" id="BT-47_scheme">Schéma du numéro d'enregistrement</entry>
<entry key="xr:Buyer_VAT_identifier" id="BT-48">Numéro de TVA intracommunautaire</entry>
<entry key="xr:Value_added_tax_point_date" id="BT-7">Date d'exigibilité de la TVA</entry>
<entry key="xr:Value_added_tax_point_date_code" id="BT-8">Code de la date d'exigibilité de la TVA</entry>
<entry key="xr:Buyer_accounting_reference" id="BT-19">Référence comptable</entry>
<entry key="xr:Deliver_to_location_identifier" id="BT-71">Identifiant du lieu de livraison</entry>
<entry key="xr:Deliver_to_location_identifier/@scheme_identifier" id="BT-71_scheme">Schéma de l'identifiant</entry>
<entry key="xr:Actual_delivery_date" id="BT-72">Date de livraison</entry>
<entry key="xr:Deliver_to_party_name" id="BT-70">Nom du destinataire</entry>
<entry key="xr:Deliver_to_address_line_1" id="BT-75">Adresse ligne 1</entry>
<entry key="xr:Deliver_to_address_line_2" id="BT-76">Adresse ligne 2</entry>
<entry key="xr:Deliver_to_address_line_3" id="BT-165">Adresse ligne 3</entry>
<entry key="xr:Deliver_to_post_code" id="BT-78">Code postal</entry>
<entry key="xr:Deliver_to_city" id="BT-77">Ville</entry>
<entry key="xr:Deliver_to_country_subdivision" id="BT-79">Région</entry>
<entry key="xr:Deliver_to_country_code" id="BT-80">Code pays</entry>
<entry key="xr:Tender_or_lot_reference" id="BT-17">Numéro d'appel d'offres</entry>
<entry key="xr:Receiving_advice_reference" id="BT-15">Référence de l'avis de réception</entry>
<entry key="xr:Despatch_advice_reference" id="BT-16">Référence de l'avis d'expédition</entry>
<entry key="xr:Business_process_type" id="BT-23">Identifiant du processus</entry>
<entry key="xr:Specification_identifier" id="BT-24">Identifiant de spécification</entry>
<entry key="xr:Invoiced_object_identifier" id="BT-18">Identifiant de l'objet</entry>
<entry key="xr:Invoiced_object_identifier/@scheme_identifier" id="BT-18_scheme">Schéma de l'identifiant de l'objet</entry>
<!-- BG 10 -->
<entry key="xr:Payee_name" id="BT-59">Nom</entry>
<entry key="xr:Payee_identifier" id="BT-60">Identifiant</entry>
<entry key="xr:Payee_identifier/@scheme_identifier" id="BT-60_scheme">Schéma de l'identifiant</entry>
<entry key="xr:Payee_legal_registration_identifier" id="BT-61">Numéro SIRET/SIREN</entry>
<entry key="xr:Payee_legal_registration_identifier/@scheme_identifier" id="BT-61_scheme">Schéma du numéro d'enregistrement</entry>
<!-- BG 24 Additonal supporting Documents -->
<entry key="xr:Supporting_document_reference" id="BT-122">Identifiant</entry>
<entry key="xr:Supporting_document_description" id="BT-123">Description</entry>
<entry key="xr:External_document_location" id="BT-124">Référence (ex. adresse Internet)</entry>
<entry key="xr:Attached_document" id="BT-125">Document joint</entry>
<entry key="xr:Attached_document/@mime_code" id="BT-125_mime_code">Format du document joint</entry>
<entry key="xr:Attached_document/@filename" id="BT-125_filename">Nom du document joint</entry>
<entry key="xrv:zeitstempel">Date/Heure</entry>
<entry key="xrv:betreff">Objet</entry>
<entry key="xrv:text">Texte</entry>
<entry key="xrv:details">Détails</entry>
<entry key="xr:Invoice_line_identifier" id="BT-126">Position</entry>
<entry key="xr:Invoice_line_note" id="BT-127">Texte libre</entry>
<entry key="xr:Invoice_line_object_identifier" id="BT-128_identifier">Identifiant de l'objet</entry>
<entry key="xr:Invoice_line_object_identifier/@scheme_identifier" id="BT-128_scheme">Schéma de l'identifiant de l'objet</entry>
<entry key="xr:Referenced_purchase_order_line_reference" id="BT-132">Numéro de ligne de commande</entry>
<entry key="xr:Invoice_line_Buyer_accounting_reference" id="BT-133">Référence comptable</entry>
<entry key="xr:Invoice_line_period_start_date" id="BT-134">Du</entry>
<entry key="xr:Invoice_line_period_end_date" id="BT-135">Au</entry>
<entry key="xr:Invoiced_quantity" id="BT-129">Quantité</entry>
<entry key="xr:Invoiced_quantity_unit_of_measure_code" id="BT-130">Unité</entry>
<entry key="xr:Item_net_price" id="BT-146">Prix unitaire (HT)</entry>
<entry key="xr:Invoice_line_net_amount" id="BT-131">Prix total (HT)</entry>
<entry key="xr:Item_price_discount" id="BT-147">Remise (HT)</entry>
<entry key="xr:Item_gross_price" id="BT-148">Prix catalogue (HT)</entry>
<entry key="xr:Item_price_base_quantity" id="BT-149">Quantité de base</entry>
<entry key="xr:Item_price_base_quantity_unit_of_measure" id="BT-150">Code de l'unité de mesure</entry>
<entry key="xr:Invoiced_item_VAT_category_code" id="BT-151">TVA</entry>
<entry key="xr:Invoiced_item_VAT_rate" id="BT-152">Taux de TVA</entry>
<entry key="xr:Item_name" id="BT-153">Désignation</entry>
<entry key="xr:Item_description" id="BT-154">Description</entry>
<entry key="xr:Item_Sellers_identifier" id="BT-155">Référence article</entry>
<entry key="xr:Item_Buyers_identifier" id="BT-156">Référence article acheteur</entry>
<entry key="xr:Item_standard_identifier" id="BT-157">Identifiant article</entry>
<entry key="xr:Item_standard_identifier/@scheme_identifier" class="BT-157_scheme">Schéma de l'identifiant article</entry>
<entry key="xr:Item_classification_identifier" id="BT-158">Code de classification article</entry>
<entry key="xr:Item_classification_identifier/@scheme_identifier" id="BT-158_scheme">Identifiant du schéma</entry>
<entry key="xr:Item_classification_identifier/@scheme_version_identifier" id="BT-158_scheme_version">Version du schéma</entry>
<entry key="xr:Item_country_of_origin" id="BT-159">Code du pays d'origine</entry>
<entry key="xr:Invoice_line_allowance_base_amount" id="BT-137">Montant de base (HT)</entry>
<entry key="xr:Invoice_line_allowance_percentage" id="BT-138">Pourcentage</entry>
<entry key="xr:Invoice_line_allowance_amount" id="BT-136">Remise (HT)</entry>
<entry key="xr:Invoice_line_allowance_reason" id="BT-139">Motif de la remise</entry>
<entry key="xr:Invoice_line_allowance_reason_code" id="BT-140">Code du motif de la remise</entry>
<entry key="xr:Invoice_line_charge_base_amount" id="BT-142">Montant de base (HT)</entry>
<entry key="xr:Invoice_line_charge_percentage" id="BT-143">Pourcentage</entry>
<entry key="xr:Invoice_line_charge_amount" id="BT-141">Frais (HT)</entry>
<entry key="xr:Invoice_line_charge_reason" id="BT-144">Motif des frais</entry>
<entry key="xr:Invoice_line_charge_reason_code" id="BT-145">Code du motif des frais</entry>
<entry key="xr:Third_party_payment_type" id="BT-DEX-001">Type de créance tierce</entry>
<entry key="xr:Third_party_payment_amount" id="BT-DEX-002">Montant de la créance tierce</entry>
<entry key="xr:Third_party_payment_description" id="BT-DEX-003">Description de la créance tierce</entry>
<entry key="uebersicht">Données de la facture électronique</entry>
<entry key="uebersichtKaeufer" id="BG-7">Informations sur l'acheteur</entry>
<entry key="uebersichtVerkaeufer" id="BG-4">Informations sur le vendeur</entry>
<entry key="uebersichtRechnungsInfo" id="invoice-data">Données de facturation</entry>
<entry key="uebersichtRechnungsuebersicht" id="BG-22">Totaux de la facture</entry>
<entry key="uebersichtFremdleistungen" id="BG-DEX-09">Créance tierce</entry>
<entry key="uebersichtUmsatzsteuer" id="BG-23">Ventilation de la TVA au niveau de la facture</entry>
<entry key="uebersichtNachlass" id="BG-20">Remise au niveau de la facture</entry>
<entry key="uebersichtZuschlaege" id="BG-21">Frais au niveau de la facture</entry>
<entry key="uebersichtRechnungAbrechnungszeitraum">Période de facturation</entry>
<entry key="uebersichtRechnungVorausgegangeneRechnungen" id="BG-3">Factures précédentes</entry>
<entry key="uebersichtZahlungInfo" id="BG-4">Informations de paiement</entry>
<entry key="uebersichtZahlungKarte" id="BG-18">Informations carte</entry>
<entry key="uebersichtZahlungLastschrift" id="BG-19">Prélèvement</entry>
<entry key="uebersichtZahlungUeberweisung" id="BG-17">Virement</entry>
<entry key="uebersichtBemerkungen" id="BG-1">Remarques sur la facture</entry>
<entry key="details">Lignes de facture</entry>
<entry key="detailsPositionAbrechnungszeitraum" id="BG-26">Période de facturation</entry>
<entry key="detailsPositionPreiseinzelheiten" id="BG-29">Détails du prix</entry>
<entry key="detailsPositionNachlaesse" id="BG-27">Remises au niveau de la ligne de facture</entry>
<entry key="detailsPositionZuschlaege" id="BG-28">Frais au niveau de la ligne de facture</entry>
<entry key="detailsPositionArtikelinformationen" id="BG-31">Informations sur l'article</entry>
<entry key="detailsPositionArtikeleigenschaften" id="BG-32">Caractéristiques de l'article</entry>
<entry key="zusaetze">Compléments</entry>
<entry key="zusaetzeVerkaeufer" id="BG-4">Informations sur le vendeur</entry>
<entry key="zusaetzeSteuervertreter" id="BG-11">Représentant fiscal du vendeur</entry>
<entry key="zusaetzeKaeufer" id="BG-7">Informations sur l'acheteur</entry>
<entry key="zusaetzeLieferung" id="BG-13">Informations de livraison</entry>
<entry key="zusaetzeVertrag">Informations contractuelles</entry>
<entry key="zusaetzeZahlungsempfaenger" id="BG-10">Bénéficiaire différent du vendeur</entry>
<entry key="laufzettel">Fiche de suivi</entry>
<entry key="laufzettelHistorie">Historique de traitement</entry>
<entry key="anlagen">Pièces jointes</entry>
<entry key="anlagenListe">Documents justificatifs</entry>
<entry key="date-format">[D]/[M]/[Y]</entry>
<entry key="datetime-format">[D]/[M]/[Y] [H]:[m]:[s]</entry>
<entry key="amount-format">###.##0,00</entry>
<entry key="percentage-format">##0,00</entry>
<entry key="at-least-two-format">###.##0,#################</entry>
<entry key="sum-of-third-party-payment-amounts" id="BT-DEX-002_sum">Total des créances tierces</entry>
<entry key="_disclaimer">Nous déclinons toute responsabilité quant à l'exactitude des données.</entry>
<entry key="_invoice-note-group">Remarques sur la facture</entry>
<entry key="_open">Ouvrir</entry>
<entry key="no-data">Aucune donnée disponible</entry>
<entry key="_net">HT</entry>
<entry key="_gross">TTC</entry>
<entry key="_no-content">Les sections sans contenu ne sont pas affichées !</entry>
<entry key="_description">Description</entry>
<entry key="_price">Prix</entry>
<entry key="_price-unit">Unité de prix</entry>
<entry key="_vat">Taux TVA</entry>
<entry key="_tax-code">Code taxe</entry>
<entry key="_total">Total</entry>
<entry key="_page">Page</entry>
</properties>

View File

@@ -8,6 +8,7 @@
xmlns:xrf="https://projekte.kosit.org/xrechnung/xrechnung-visualization/functions">
<xsl:decimal-format name="de" decimal-separator="," grouping-separator="." NaN="" />
<xsl:decimal-format name="fr" decimal-separator="," grouping-separator="." NaN="" />
<xsl:decimal-format name="en" decimal-separator="." grouping-separator="," NaN="" />
<xsl:template name="uebersicht">

View File

@@ -1,176 +1,210 @@
/**
* *********************************************************************
* <p>
* Copyright 2019 Jochen Staerk
* <p>
* Use is subject to license terms.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* <p>
* See the License for the specific language governing permissions and
* limitations under the License.
* <p>
* **********************************************************************
*/
package org.mustangproject.ZUGFeRD;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.ZUGFeRD.ZUGFeRDVisualizer.Language;
import org.mustangproject.util.ByteArraySearcher;
import javax.xml.transform.TransformerException;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class VisualizationTest extends ResourceCase {
final String TARGET_PDF_CII = "./target/testout-Visualization-cii.pdf";
final String TARGET_PDF_UBL = "./target/testout-Visualization-cii.pdf";
public void testCIIVisualizationBasic() {
this.runZUGFeRDVisualization("factur-x.xml", "factur-x-vis.fr.html", Language.FR);
}
public void testCIIVisualizationExtended() {
this.runZUGFeRDVisualization("factur-x-extended.xml", "factur-x-vis-extended.de.html", Language.DE);
}
public void testUBLCreditNoteVisualizationBasic() {
this.runZUGFeRDVisualization("ubl-creditnote.xml", "factur-x-vis-ubl-creditnote.en.html", Language.EN);
}
public void testUBLVisualizationBasic() {
this.runZUGFeRDVisualization("ubl/01.01a-INVOICE.ubl.xml", "factur-x-vis-ubl.en.html", Language.EN);
}
private void runZUGFeRDVisualization(String inputFilename, String resultFileName, Language lang) {
File CIIinputFile = getResourceAsFile(inputFilename);
String expected = null;
String result = null;
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
result = zvi.visualize(CIIinputFile.getAbsolutePath(), lang);
Files.write(Paths.get("./target/testout-" + resultFileName), result.getBytes(StandardCharsets.UTF_8));
File expectedResult = getResourceAsFile(resultFileName);
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8)
;
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
} catch (TransformerException e) {
fail("TransformerException should not happen: " + e.getMessage());
} catch (IOException e) {
fail("IOException should not happen: " + e.getMessage());
} catch (ParserConfigurationException e) {
fail("ParserConfigurationException should not happen: " + e.getMessage());
}
assertNotNull(result);
/* remove file endings so that tests can also pass after checking
out from git with arbitrary options (which may include CSRF changes)
*/
assertEquals(expected.replace("\r", "")
.replace("\n", "")
.replace("\t", "")
.replace(" ", ""), result.replace("\r", "")
.replace("\n", "")
.replace("\t", "")
.replace(" ", ""));
}
public void testPDFVisualizationCII() {
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
// the writing part
String expected = null;
String result = null;
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII);
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
}
try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
} catch (IOException e) {
fail("IOException should not occur");
}
}
public void testPDFVisualizationUBL() {
File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.xml");
// the writing part
String sourceFilename = "factur-x.xml";
String expected = null;
String result = null;
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL);
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
}
try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
} catch (IOException e) {
fail("IOException should not occur");
}
}
public void testPDFVisualizationUBLCreditNote() {
File UBLinputFile = getResourceAsFile("ubl/UBL-CreditNote-2.1-Example.ubl.xml");
// the writing part
String sourceFilename = "factur-x.xml";
String expected = null;
String result = null;
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL);
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
}
try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
} catch (IOException e) {
fail("IOException should not occur");
}
}
}
/**
* *********************************************************************
* <p>
* Copyright 2019 Jochen Staerk
* <p>
* Use is subject to license terms.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* <p>
* See the License for the specific language governing permissions and
* limitations under the License.
* <p>
* **********************************************************************
*/
package org.mustangproject.ZUGFeRD;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.ZUGFeRD.ZUGFeRDVisualizer.Language;
import org.mustangproject.util.ByteArraySearcher;
import javax.xml.transform.TransformerException;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class VisualizationTest extends ResourceCase {
final String TARGET_PDF_CII = "./target/testout-Visualization-cii.pdf";
final String TARGET_PDF_UBL = "./target/testout-Visualization-cii.pdf";
public void testCIIVisualizationBasic() {
this.runZUGFeRDVisualization("factur-x.xml", "factur-x-vis.fr.html", Language.FR);
}
public void testCIIVisualizationExtended() {
this.runZUGFeRDVisualization("factur-x-extended.xml", "factur-x-vis-extended.de.html", Language.DE);
}
public void testUBLCreditNoteVisualizationBasic() {
this.runZUGFeRDVisualization("ubl-creditnote.xml", "factur-x-vis-ubl-creditnote.en.html", Language.EN);
}
public void testUBLVisualizationBasic() {
this.runZUGFeRDVisualization("ubl/01.01a-INVOICE.ubl.xml", "factur-x-vis-ubl.en.html", Language.EN);
}
private void runZUGFeRDVisualization(String inputFilename, String resultFileName, Language lang) {
File CIIinputFile = getResourceAsFile(inputFilename);
String expected = null;
String result = null;
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
result = zvi.visualize(CIIinputFile.getAbsolutePath(), lang);
Files.write(Paths.get("./target/testout-" + resultFileName), result.getBytes(StandardCharsets.UTF_8));
File expectedResult = getResourceAsFile(resultFileName);
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8)
;
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
} catch (TransformerException e) {
fail("TransformerException should not happen: " + e.getMessage());
} catch (IOException e) {
fail("IOException should not happen: " + e.getMessage());
} catch (ParserConfigurationException e) {
fail("ParserConfigurationException should not happen: " + e.getMessage());
}
assertNotNull(result);
/* remove file endings so that tests can also pass after checking
out from git with arbitrary options (which may include CSRF changes)
*/
assertEquals(expected.replace("\r", "")
.replace("\n", "")
.replace("\t", "")
.replace(" ", ""), result.replace("\r", "")
.replace("\n", "")
.replace("\t", "")
.replace(" ", ""));
}
public void testPDFVisualizationCII() {
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII);
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
}
try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
assertTrue(ByteArraySearcher.contains(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), "<rdf:li>de</rdf:li>".getBytes()));
} catch (IOException e) {
fail("IOException should not occur");
}
}
public void testPDFVisualizationCIIEnglish() {
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII, Language.EN);
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
}
try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
assertTrue(ByteArraySearcher.contains(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), "<rdf:li>en</rdf:li>".getBytes()));
} catch (IOException e) {
fail("IOException should not occur");
}
}
public void testPDFVisualizationCIIFrench() {
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII, Language.FR);
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
}
try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
assertTrue(ByteArraySearcher.contains(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), "<rdf:li>fr</rdf:li>".getBytes()));
} catch (IOException e) {
fail("IOException should not occur");
}
}
public void testPDFVisualizationUBL() {
File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.xml");
// the writing part
String sourceFilename = "factur-x.xml";
String expected = null;
String result = null;
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL);
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
}
try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
} catch (IOException e) {
fail("IOException should not occur");
}
}
public void testPDFVisualizationUBLCreditNote() {
File UBLinputFile = getResourceAsFile("ubl/UBL-CreditNote-2.1-Example.ubl.xml");
// the writing part
String sourceFilename = "factur-x.xml";
String expected = null;
String result = null;
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL);
} catch (UnsupportedOperationException e) {
fail("UnsupportedOperationException should not happen: " + e.getMessage());
} catch (IllegalArgumentException e) {
fail("IllegalArgumentException should not happen: " + e.getMessage());
}
try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
} catch (IOException e) {
fail("IOException should not occur");
}
}
}