Factur-X/ZUGFeRD: in »Factur-X/ZUGFeRD« umbenannt
authorMoritz Bunkus <m.bunkus@linet.de>
Thu, 26 Nov 2020 13:04:32 +0000 (14:04 +0100)
committerMoritz Bunkus <m.bunkus@linet.de>
Thu, 26 Nov 2020 14:48:00 +0000 (15:48 +0100)
Mit ZUGFeRD-Standard Version 2.1.1 ist der offizielle Name des
EU-Standards schlicht Factur-X. ZUGFeRD ist nur noch der tolerierte
alte Name.

In der Oberfläche ist nun überall von »Factur-X/ZUGFeRD« die Rede.

Im Quellcode heißen die Module hingegen weiterhin `SL::…::ZUGFeRD`,
weil die Umstellung ansonsten zu groß und irgendwo auch nicht so nötig
ist.

Es ändern sich auch die ganzen Namen in den Metadaten des PDFs und der
XML-Datei:

• Namensraum in der für Factur-X/ZUGFeRD relevanten XML-Elemente in
  den XMP-Metadaten im PDF
• Name des Dateianhangs der Rechnungs-XML im PDF (»factur-x.xml«)
• Standard-Identifier in der Rechnungs-XML

22 files changed:
SL/Controller/ClientConfig.pm
SL/Controller/CustomerVendor.pm
SL/Controller/SimpleSystemSetting.pm
SL/Controller/ZUGFeRD.pm
SL/DB/Helper/PDF_A.pm
SL/DB/Helper/ZUGFeRD.pm
SL/Helper/CreatePDF.pm
SL/Template/LaTeX.pm
SL/ZUGFeRD.pm
bin/mozilla/ct.pl
bin/mozilla/generictranslations.pl
bin/mozilla/io.pl
doc/dokumentation.xml
locale/de/all
menus/user/00-erp.yaml
templates/pdf/pdf_a_metadata.xmp
templates/webpages/client_config/_features.html
templates/webpages/ct/search.html
templates/webpages/customer_vendor/tabs/billing.html
templates/webpages/generictranslations/edit_zugferd_notes.html
templates/webpages/simple_system_setting/_bank_account_form.html
templates/webpages/zugferd/form.html

index 9bf0eda..1212512 100644 (file)
@@ -21,12 +21,13 @@ use SL::Controller::TopQuickSearch;
 use SL::DB::Helper::AccountingPeriod qw(get_balance_startdate_method_options);
 use SL::Helper::ShippedQty;
 use SL::VATIDNr;
+use SL::ZUGFeRD;
 
 __PACKAGE__->run_before('check_auth');
 
 use Rose::Object::MakeMethods::Generic (
   'scalar --get_set_init' => [ qw(defaults all_warehouses all_weightunits all_languages all_currencies all_templates all_price_sources h_unit_name available_quick_search_modules available_shipped_qty_item_identity_fields
-                                  all_project_statuses all_project_types
+                                  all_project_statuses all_project_types zugferd_settings
                                   posting_options payment_options accounting_options inventory_options profit_options balance_startdate_method_options
                                   displayable_name_specs_by_module) ],
 );
@@ -166,6 +167,7 @@ sub init_all_templates   { +{ SL::Template->available_templates }
 sub init_h_unit_name     { first { SL::DB::Manager::Unit->find_by(name => $_) } qw(Std h Stunde)                         }
 sub init_all_project_types    { SL::DB::Manager::ProjectType->get_all_sorted                                             }
 sub init_all_project_statuses { SL::DB::Manager::ProjectStatus->get_all_sorted                                           }
+sub init_zugferd_settings     { \@SL::ZUGFeRD::customer_settings                                                         }
 
 sub init_posting_options {
   [ { title => t8("never"),           value => 0           },
index 8b10f2c..e8f1c5a 100644 (file)
@@ -11,6 +11,7 @@ use SL::Helper::Flash;
 use SL::Locale::String;
 use SL::Util qw(trim);
 use SL::Webdav;
+use SL::ZUGFeRD;
 use SL::Controller::Helper::GetModels;
 use SL::Controller::Helper::ReportGenerator;
 use SL::Controller::Helper::ParseFilter;
@@ -40,7 +41,7 @@ use SL::DB::Order;
 use Data::Dumper;
 
 use Rose::Object::MakeMethods::Generic (
-  'scalar --get_set_init' => [ qw(customer_models vendor_models) ],
+  'scalar --get_set_init' => [ qw(customer_models vendor_models zugferd_settings) ],
 );
 
 # safety
@@ -1235,6 +1236,13 @@ sub init_vendor_models {
   );
 }
 
+sub init_zugferd_settings {
+  return [
+    [ -1, t8('Use settings from client configuration') ],
+    @SL::ZUGFeRD::customer_settings,
+  ],
+}
+
 sub _new_customer_vendor_object {
   my ($self) = @_;
 
index aaca8e9..f8dd4bc 100644 (file)
@@ -35,7 +35,7 @@ my %supported_types = (
       { method => 'bank',                                      title => t8('Bank'), },
       { method => 'bank_code',                                 title => t8('Bank code'), },
       { method => 'bic',                                       title => t8('BIC'), },
-      {                                                        title => t8('Use for ZUGFeRD'), formatter => sub { $_[0]->use_for_zugferd ? t8('yes') : t8('no') } },
+      {                                                        title => t8('Use for Factur-X/ZUGFeRD'), formatter => sub { $_[0]->use_for_zugferd ? t8('yes') : t8('no') } },
       { method => 'reconciliation_starting_date_as_date',      title => t8('Date'),    align => 'right' },
       { method => 'reconciliation_starting_balance_as_number', title => t8('Balance'), align => 'right' },
     ],
index 29d7e07..cad98a3 100644 (file)
@@ -17,7 +17,7 @@ sub action_upload_zugferd {
   my ($self, %params) = @_;
 
   $self->setup_zugferd_action_bar;
-  $self->render('zugferd/form', title => $::locale->text('ZUGFeRD import'));
+  $self->render('zugferd/form', title => $::locale->text('Factur-X/ZUGFeRD import'));
 }
 
 sub action_import_zugferd {
@@ -31,15 +31,15 @@ sub action_import_zugferd {
   if ($info->{result} != SL::ZUGFeRD::RES_OK()) {
     # An error occurred; log message from parser:
     $::lxdebug->message(LXDebug::DEBUG1(), "Could not extract ZUGFeRD data, error message: " . $info->{message});
-    die t8("Could not extract ZUGFeRD data, data and error message:") . $info->{message};
+    die t8("Could not extract Factur-X/ZUGFeRD data, data and error message:") . $info->{message};
   }
   # valid ZUGFeRD metadata
   my $dom   = XML::LibXML->load_xml(string => $info->{invoice_xml});
 
   # 1. check if ZUGFeRD SellerTradeParty has a VAT-ID
   my $ustid = $dom->findnodes('//ram:SellerTradeParty/ram:SpecifiedTaxRegistration')->string_value;
-  die t8("No VAT Info for this ZUGFeRD invoice," .
-         " please ask your vendor to add this for his ZUGFeRD data.") unless $ustid;
+  die t8("No VAT Info for this Factur-X/ZUGFeRD invoice," .
+         " please ask your vendor to add this for his Factur-X/ZUGFeRD data.") unless $ustid;
 
   $ustid = SL::VATIDNr->normalize($ustid);
 
index 1e1e172..467d4c1 100644 (file)
@@ -58,7 +58,7 @@ sub create_pdf_a_print_options {
       },
       zugferd              => {
         conformance_level  => 'EXTENDED',
-        document_file_name => 'ZUGFeRD-invoice.xml',
+        document_file_name => 'factur-x.xml',
         document_type      => 'INVOICE',
         version            => '1.0',
       },
index 5455398..017bbc5 100644 (file)
@@ -14,6 +14,7 @@ use SL::Helper::ISO3166;
 use SL::Helper::ISO4217;
 use SL::Helper::UNECERecommendation20;
 use SL::VATIDNr;
+use SL::ZUGFeRD qw(:PROFILES);
 
 use Carp;
 use Encode qw(encode);
@@ -24,6 +25,13 @@ use XML::Writer;
 
 my @line_names = qw(LineOne LineTwo LineThree);
 
+my %standards_ids = (
+  PROFILE_FACTURX_EXTENDED() => 'urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended',
+sub _is_profile {
+  my ($self, @profiles) = @_;
+  return any { $self->{_zugferd}->{profile} == $_ } @profiles;
+}
+
 sub _u8 {
   my ($value) = @_;
   return encode('UTF-8', $value // '');
@@ -340,14 +348,14 @@ sub _exchanged_document_context {
   #   <rsm:ExchangedDocumentContext>
   $params{xml}->startTag("rsm:ExchangedDocumentContext");
 
-  if ($self->customer->create_zugferd_invoices_for_this_customer == 2) {
+  if ($self->{_zugferd}->{test_mode}) {
     $params{xml}->startTag("ram:TestIndicator");
     $params{xml}->dataElement("udt:Indicator", "true");
     $params{xml}->endTag;
   }
 
   $params{xml}->startTag("ram:GuidelineSpecifiedDocumentContextParameter");
-  $params{xml}->dataElement("ram:ID", "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended");
+  $params{xml}->dataElement("ram:ID", $standards_ids{ $self->{_zugferd}->{profile} });
   $params{xml}->endTag;
   $params{xml}->endTag;
   #   </rsm:ExchangedDocumentContext>
@@ -608,7 +616,7 @@ sub _validate_data {
     $result{bank_account} = scalar(@{ $bank_accounts }) == 1 ? $bank_accounts->[0] : first { $_->use_for_zugferd } @{ $bank_accounts };
 
     if (!$result{bank_account}) {
-      SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('No bank account flagged for ZUGFeRD usage was found.'));
+      SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('No bank account flagged for Factur-X/ZUGFeRD usage was found.'));
     }
   }
 
@@ -617,6 +625,11 @@ sub _validate_data {
 
 sub create_zugferd_data {
   my ($self)        = @_;
+  $self->{_zugferd} = { SL::ZUGFeRD->convert_customer_setting($self->customer->create_zugferd_invoices_for_this_customer) };
+
+  if (!$standards_ids{ $self->{_zugferd}->{profile} }) {
+    croak "Profile '" . $self->{_zugferd}->{profile} . "' is not supported";
+  }
 
   my $output        = '';
 
@@ -655,7 +668,7 @@ sub create_zugferd_xmp_data {
 
   return {
     conformance_level  => 'EXTENDED',
-    document_file_name => 'ZUGFeRD-invoice.xml',
+    document_file_name => 'factur-x.xml',
     document_type      => 'INVOICE',
     version            => '1.0',
   };
index cedbb49..06fb819 100644 (file)
@@ -281,8 +281,8 @@ sub _maybe_attach_zugferd_data {
     pdf_a           => $record->create_pdf_a_print_options(zugferd_xmp_data => $record->create_zugferd_xmp_data),
     pdf_attachments => [
       { source       => $xmlfile,
-        name         => 'ZUGFeRD-invoice.xml',
-        description  => $::locale->text('ZUGFeRD invoice'),
+        name         => 'factur-x.xml',
+        description  => $::locale->text('Factur-X/ZUGFeRD invoice'),
         relationship => '/Alternative',
         mime_type    => 'text/xml',
       }
index b2b6838..bc03eb3 100644 (file)
@@ -394,8 +394,8 @@ sub _embed_file_directive {
   my ($self, $file) = @_;
 
   # { source      => $xmlfile,
-  #   name        => 'ZUGFeRD-invoice.xml',
-  #   description => $::locale->text('ZUGFeRD invoice'), }
+  #   name        => 'factur-x.xml',
+  #   description => $::locale->text('Factur-X/ZUGFeRD invoice'), }
 
   my $file_name  =  blessed($file->{source}) && $file->{source}->can('filename') ? $file->{source}->filename : "" . $file->{source}->filename;
   my $embed_name =  $file->{name} // $file_name;
index 780122c..02d73de 100644 (file)
@@ -9,6 +9,15 @@ use Data::Dumper;
 use List::Util qw(first);
 use XML::LibXML;
 
+use SL::Locale::String qw(t8);
+
+use parent qw(Exporter);
+our @EXPORT_PROFILES = qw(PROFILE_FACTURX_EXTENDED);
+our @EXPORT_OK       = (@EXPORT_PROFILES);
+our %EXPORT_TAGS     = (PROFILES => \@EXPORT_PROFILES);
+
+use constant PROFILE_FACTURX_EXTENDED => 0;
+
 use constant RES_OK                              => 0;
 use constant RES_ERR_FILE_OPEN                   => 1;
 use constant RES_ERR_NO_XMP_METADATA             => 2;
@@ -16,6 +25,23 @@ use constant RES_ERR_NO_XML_INVOICE              => 3;
 use constant RES_ERR_NOT_ZUGFERD                 => 4;
 use constant RES_ERR_UNSUPPORTED_ZUGFERD_VERSION => 5;
 
+our @customer_settings = (
+  [ 0,                                  t8('Do not create Factur-X/ZUGFeRD invoices')                                    ],
+  [ PROFILE_FACTURX_EXTENDED() * 2 + 1, t8('Create with profile \'Factur-X 1.0.05/ZUGFeRD 2.1.1 extended\'')             ],
+  [ PROFILE_FACTURX_EXTENDED() * 2 + 2, t8('Create with profile \'Factur-X 1.0.05/ZUGFeRD 2.1.1 extended\' (test mode)') ],
+);
+
+sub convert_customer_setting {
+  my ($class, $customer_setting) = @_;
+
+  return () if ($customer_setting <= 0) || ($customer_setting >= scalar(@customer_settings));
+
+  return (
+    profile   => int(($customer_setting - 1) / 2),
+    test_mode => ($customer_setting - 1) % 2,
+  );
+}
+
 sub _extract_zugferd_invoice_xml {
   my $doc        = shift;
   my $names_dict = $doc->getValue($doc->getRootDict->{Names}) or return {};
@@ -109,11 +135,16 @@ sub extract_from_pdf {
     next unless $ns;
 
     if ($ns->getData =~ m{urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0}) {
-      $zugferd_version = '2p0';
+      $zugferd_version = 'zugferd:2p0';
+      last;
+    }
+
+    if ($ns->getData =~ m{urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0}) {
+      $zugferd_version = 'factur-x:1p0';
       last;
     }
 
-    if ($ns->getData =~ m{zugferd}i) {
+    if ($ns->getData =~ m{zugferd|factur-x}i) {
       $zugferd_version = 'unsupported';
       last;
     }
@@ -122,14 +153,14 @@ sub extract_from_pdf {
   if (!$zugferd_version) {
     return {
       result  => RES_ERR_NOT_ZUGFERD(),
-      message => $::locale->text('The XMP metadata does not declare the ZUGFeRD data.'),
+      message => $::locale->text('The XMP metadata does not declare the Factur-X/ZUGFeRD data.'),
     };
   }
 
-  if ($zugferd_version !~ m{^2p}) {
+  if ($zugferd_version eq 'unsupported') {
     return {
       result  => RES_ERR_UNSUPPORTED_ZUGFERD_VERSION(),
-      message => $::locale->text('The ZUGFeRD version used is not supported.'),
+      message => $::locale->text('The Factur-X/ZUGFeRD version used is not supported.'),
     };
   }
 
@@ -138,7 +169,7 @@ sub extract_from_pdf {
   if (!defined $invoice_xml) {
     return {
       result  => RES_ERR_NO_XML_INVOICE(),
-      message => $::locale->text('The ZUGFeRD XML invoice was not found.'),
+      message => $::locale->text('The Factur-X/ZUGFeRD XML invoice was not found.'),
     };
   }
 
@@ -159,7 +190,7 @@ __END__
 
 =head1 NAME
 
-SL::ZUGFeRD - Helper functions for dealing with PDFs containing ZUGFeRD invoice data
+SL::ZUGFeRD - Helper functions for dealing with PDFs containing Factur-X/ZUGFeRD invoice data
 
 =head1 SYNOPSIS
 
@@ -182,10 +213,11 @@ SL::ZUGFeRD - Helper functions for dealing with PDFs containing ZUGFeRD invoice
 
 =item C<extract_from_pdf> C<$file_name>
 
-Opens an existing PDF in the file system and tries to extract ZUGFeRD
-invoice data from it. First it'll parse the XMP metadata and look for
-the ZUGFeRD declaration inside. If the declaration isn't found or the
-declared version isn't 2p0, an error is returned.
+Opens an existing PDF in the file system and tries to extract
+Factur-X/ZUGFeRD invoice data from it. First it'll parse the XMP
+metadata and look for the Factur-X/ZUGFeRD declaration inside. If the
+declaration isn't found or the declared version isn't 2p0, an error is
+returned.
 
 Otherwise it'll continue to look through all embedded files in the
 PDF. The first embedded XML file with a root node of
@@ -198,7 +230,7 @@ can be one of the following constants:
 
 =item C<RES_OK> (0): parsing was OK; the returned hash will also
 contain the keys C<xmp_metadata> and C<invoice_xml> which will contain
-the XML text of the metadata & the ZUGFeRD invoice.
+the XML text of the metadata & the Factur-X/ZUGFeRD invoice.
 
 =item C<RES_ERR_…> (all values E<gt> 0): parsing failed; the hash will
 also contain a key C<message> which contains a human-readable
index e8c6efd..87eb0d8 100644 (file)
@@ -58,6 +58,7 @@ use SL::DB::DeliveryTerm;
 use SL::ReportGenerator;
 use SL::Locale::String qw(t8);
 use SL::MoreCommon qw(uri_encode);
+use SL::ZUGFeRD;
 
 require "bin/mozilla/common.pl";
 require "bin/mozilla/reportgenerator.pl";
@@ -69,9 +70,7 @@ use strict;
 
 sub _zugferd_settings {
   return ([ -1, $::locale->text('Use settings from client configuration') ],
-          [  0, $::locale->text('Do not create ZUGFeRD invoices') ],
-          [  1, $::locale->text('Create ZUGFeRD invoices') ],
-          [  2, $::locale->text('Create ZUGFeRD invoices in test mode') ]);
+          @SL::ZUGFeRD::customer_settings);
 }
 
 sub search {
@@ -164,7 +163,7 @@ sub list_names {
   push @options, $locale->text('Billing/shipping address (country)') . " : $form->{addr_country}" if $form->{addr_country};
   push @options, $locale->text('Billing/shipping address (GLN)')     . " : $form->{addr_gln}"     if $form->{addr_gln};
   push @options, $locale->text('Quick Search')                       . " : $form->{all}"          if $form->{all};
-  push @options, $locale->text('ZUGFeRD settings')                   . " : $zugferd_filter"       if $zugferd_filter;
+  push @options, $locale->text('Factur-X/ZUGFeRD settings')          . " : $zugferd_filter"       if $zugferd_filter;
 
   if ($form->{business_id}) {
     my $business = SL::DB::Manager::Business->find_by(id => $form->{business_id});
@@ -232,7 +231,7 @@ sub list_names {
     'creditlimit'       => { 'text' => $locale->text('Credit Limit'), },
     'ustid'             => { 'text' => $locale->text('VAT ID'), },
     'commercial_court'  => { 'text' => $locale->text('Commercial court'), },
-    create_zugferd_invoices => { text => $locale->text('ZUGFeRD settings'), },
+    create_zugferd_invoices => { text => $locale->text('Factur-X/ZUGFeRD settings'), },
     %column_defs_cvars,
   );
 
index 3481fca..4e6d263 100644 (file)
@@ -227,7 +227,7 @@ sub edit_zugferd_notes {
 
   setup_generictranslations_edit_zugferd_notes_action_bar();
 
-  $::form->{title} = $::locale->text('Edit ZUGFeRD notes');
+  $::form->{title} = $::locale->text('Edit Factur-X/ZUGFeRD notes');
   $::form->header;
   print $::form->parse_html_template('generictranslations/edit_zugferd_notes');
 }
@@ -248,7 +248,7 @@ sub save_zugferd_notes {
     );
   }
 
-  $::form->{message} = $::locale->text('The ZUGFeRD notes have been saved.');
+  $::form->{message} = $::locale->text('The Factur-X/ZUGFeRD notes have been saved.');
 
   edit_zugferd_notes();
 }
index 0362e13..3f43c15 100644 (file)
@@ -2166,8 +2166,8 @@ sub _maybe_attach_zugferd_data {
     $form->{TEMPLATE_DRIVER_OPTIONS}->{pdf_a}           = $record->create_pdf_a_print_options(zugferd_xmp_data => $record->create_zugferd_xmp_data);
     $form->{TEMPLATE_DRIVER_OPTIONS}->{pdf_attachments} = [
       { source       => $xmlfile,
-        name         => 'ZUGFeRD-invoice.xml',
-        description  => $::locale->text('ZUGFeRD invoice'),
+        name         => 'factur-x.xml',
+        description  => $::locale->text('Factur-X/ZUGFeRD invoice'),
         relationship => '/Alternative',
         mime_type    => 'text/xml',
       }
index 90fc6e5..11f0d4e 100644 (file)
@@ -7261,7 +7261,7 @@ document_path = /var/local/kivi_documents
                        </orderedlist>
 
                        <para>Wenn diese Voraussetzungen erfüllt sind, kann die Rechnung
-                       über „Finanzbuchhaltung“ → „ZUGFeRD Import“ über die „Durchsuchen“
+                       über „Finanzbuchhaltung“ → „Factur-X-/ZUGFeRD-Import“ über die „Durchsuchen“
                        Schaltfläche ausgewählt werden und über die Schaltfläche „Import“
                        eingeladen werden. Es öffnet sich daraufhin die Kreditorenbuchung.
                        Die auslesbaren Daten aus dem eingebetteten XML der PDF Datei
index 789c953..bcbbe31 100755 (executable)
@@ -701,7 +701,7 @@ $self->{texts} = {
   'Cost Center'                 => 'Kostenstelle',
   'Costs'                       => 'Kosten',
   'Could not create new project #1' => 'Neues Projekt #1 kann nicht angelegt werden',
-  'Could not extract ZUGFeRD data, data and error message:' => 'Konnte keine ZUGFeRD Daten extrahieren, folgende Fehlermeldung und das PDF:',
+  'Could not extract Factur-X/ZUGFeRD data, data and error message:' => 'Konnte keine Factur-X-/ZUGFeRD-Daten extrahieren, folgende Fehlermeldung und das PDF:',
   'Could not find an entry for this part in the pricegroup.' => 'Konnte keine Eintrag für diesen Artikel in der Preisgruppe finden.',
   'Could not load class #1 (#2): "#3"' => 'Konnte Klasse #1 (#2) nicht laden: "#3"',
   'Could not load class #1, #2' => 'Konnte Klasse #1 nicht laden: "#2"',
@@ -722,8 +722,6 @@ $self->{texts} = {
   'Create Date'                 => 'Erstelldatum',
   'Create HTML'                 => 'HTML erzeugen',
   'Create PDF'                  => 'PDF erzeugen',
-  'Create ZUGFeRD invoices'     => 'ZUGFeRD-Rechnungen erzeugen',
-  'Create ZUGFeRD invoices in test mode' => 'ZUGFeRD-Rechnungen im Testmodus erzeugen',
   'Create a new background job' => 'Einen neuen Hintergrund-Job anlegen',
   'Create a new client'         => 'Einen neuen Mandanten anlegen',
   'Create a new delivery term'  => 'Neue Lieferbedingungen anlegen',
@@ -777,8 +775,10 @@ $self->{texts} = {
   'Create new version'          => 'Neue Version anlegen',
   'Create one from the context menu by right-clicking on this text.' => 'Erstellen Sie einen aus dem Kontextmenü, indem Sie auf diesen Text rechtsklicken.',
   'Create order'                => 'Auftrag erstellen',
-  'Create sales invoices with ZUGFeRD data' => 'Verkaufsrechnungen mit ZUGFeRD-Daten erzeugen',
+  'Create sales invoices with Factur-X/ZUGFeRD data' => 'Verkaufsrechnungen mit Factur-X-/ZUGFeRD-Daten erzeugen',
   'Create tables'               => 'Tabellen anlegen',
+  'Create with profile \'Factur-X 1.0.05/ZUGFeRD 2.1.1 extended\'' => 'Mit Profil »Factur-X 1.0.05/ZUGFeRD 2.1.1 extended«',
+  'Create with profile \'Factur-X 1.0.05/ZUGFeRD 2.1.1 extended\' (test mode)' => 'Mit Profil »Factur-X 1.0.05/ZUGFeRD 2.1.1 extended« (Test-Modus)',
   'Created by'                  => 'Erstellt von',
   'Created for'                 => 'Erstellt für',
   'Created on'                  => 'Erstellt am',
@@ -1048,7 +1048,7 @@ $self->{texts} = {
   'Displayable Name Preferences' => 'Einstellungen für Anzeigenamen',
   'Do not change the tax rate of taxkey 0.' => 'Ändern Sie nicht den Steuersatz vom Steuerschlüssel 0.',
   'Do not check for duplicates' => 'Nicht nach Dubletten suchen',
-  'Do not create ZUGFeRD invoices' => 'Keine ZUGFeRD-Rechnungen erzeugen',
+  'Do not create Factur-X/ZUGFeRD invoices' => 'Keine Factur-X-/ZUGFeRD-Rechnungen erzeugen',
   'Do not link to a project.'   => 'Nicht mit einem Projekt verknüpfen.',
   'Do not modify this position' => 'Diese Position nicht verändern',
   'Do not run the task server for this client' => 'Task-Server nicht für diesen Mandanten ausführen',
@@ -1170,6 +1170,7 @@ $self->{texts} = {
   'Edit Dunning'                => 'Mahnungen konfigurieren',
   'Edit Dunning Process Config' => 'Mahnwesenkonfiguration bearbeiten',
   'Edit Employee #1'            => 'Benutzer #1 bearbeiten',
+  'Edit Factur-X/ZUGFeRD notes' => 'Factur-X-/ZUGFeRD-Notizen bearbeiten',
   'Edit Follow-Up'              => 'Wiedervorlage bearbeiten',
   'Edit Follow-Up for #1'       => 'Wiedervorlage für #1 bearbeiten',
   'Edit General Ledger Transaction' => 'Buchung im Hauptbuch bearbeiten',
@@ -1194,7 +1195,6 @@ $self->{texts} = {
   'Edit Vendor'                 => 'Lieferant editieren',
   'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
   'Edit Warehouse'              => 'Lager bearbeiten',
-  'Edit ZUGFeRD notes'          => 'ZUGFeRD-Notizen bearbeiten',
   'Edit acceptance status'      => 'Abnahmestatus bearbeiten',
   'Edit additional articles'    => 'Zusätzliche Artikel bearbeiten',
   'Edit all drafts'             => 'Entwürfe von allen Benutzern bearbeiten',
@@ -1432,6 +1432,10 @@ $self->{texts} = {
   'Extended status'             => 'Erweiterter Status',
   'Extension Of Time'           => 'Dauerfristverlängerung',
   'Factor'                      => 'Faktor',
+  'Factur-X/ZUGFeRD import'     => 'Factur-X-/ZUGFeRD-Import',
+  'Factur-X/ZUGFeRD invoice'    => 'Factur-X-/ZUGFeRD-Rechnung',
+  'Factur-X/ZUGFeRD notes for each invoice' => 'Factur-X-/ZUGFeRD-Notizen für jede Rechnung',
+  'Factur-X/ZUGFeRD settings'   => 'Factur-X-/ZUGFeRD-Einstellungen',
   'Fax'                         => 'Fax',
   'Features'                    => 'Features',
   'Feb'                         => 'Feb',
@@ -1618,7 +1622,7 @@ $self->{texts} = {
   'If disabled purchase invoices can only be created by conversion from existing requests for quotations, purchase orders and purchase delivery orders.' => 'Falls deaktiviert, so können Einkaufsrechnungen nur durch Umwandlung aus bestehenden Preisanfragen, Lieferantenaufträgen und Einkaufslieferscheinen angelegt werden.',
   'If disabled sales orders cannot be converted into sales invoices directly.' => 'Falls deaktiviert, so können Verkaufsaufträge nicht direkt in Verkaufsrechnungen umgewandelt werden.',
   'If disabled sales quotations cannot be converted into sales invoices directly.' => 'Falls deaktiviert, so können Verkaufsangebote nicht direkt in Verkaufsrechnungen umgewandelt werden.',
-  'If enabled ZUGFeRD-conformant sales invoice PDFs will be created.' => 'Falls aktiviert, werden ZUGFeRD-konforme PDFs für Verkaufsrechnungen erzeugt.',
+  'If enabled Factur-X/ZUGFeRD conformant sales invoice PDFs will be created.' => 'Falls aktiviert, werden Factur-X-/ZUGFeRD-konforme PDFs für Verkaufsrechnungen erzeugt.',
   'If enabled a column will be shown in sales and purchase orders that lists both the amount and the value not shipped yet for each item.' => 'Falls eingeschaltet, wird für jede Position in Auftragsbestätigungen und Lieferantenaufträgen eine Spalte mit noch nicht gelieferter Menge und Wert angezeigt.',
   'If enabled a warning will be shown in purchase delivery orders on workflow to invoices if positions are not stocked in.' => 'Falls aktiviert, wird eine Warnung beim Workflow von Einkaufslieferscheinen zu Rechnungen ausgegeben, wenn die Positionen noch nicht eingelagert sind.',
   'If enabled a warning will be shown in sales and purchase orders if there are two or more positions of the same part (new controller only).' => 'Falls eingeschaltet, wird eine Warnung angezeigt, wenn der Auftrag mehrere gleiche Artikel enthält (nur neuer Controller).',
@@ -1636,7 +1640,7 @@ $self->{texts} = {
   'If the counted quantity differs more than this threshold from the quantity in the database, a warning will be shown. Set to 0 to switch of this feature.' => 'Wenn die gezählte Menge mehr als diesen Schwellenwert von der Menge in der Datenbank abweicht, wird eine Warnmeldung angezeigt. Setzen Sie den Schwellenwert auf 0, um dieses Feature abzuschalten.',
   'If the database user listed above does not have the right to create a database then enter the name and password of the superuser below:' => 'Falls der oben genannte Datenbankbenutzer nicht die Berechtigung zum Anlegen neuer Datenbanken hat, so können Sie hier den Namen und das Passwort des Datenbankadministratoraccounts angeben:',
   'If the default transfer out always succeed use this bin for negative stock quantity.' => 'Standardlagerplatz für Auslagern ohne Prüfung auf Bestand',
-  'If the test mode is enabled, the ZUGFeRD invoices will be flagged so that they\'re only fit to be used for testing purposes.' => 'Wenn der Testmodus aktiviert ist, werden ZUGFeRD-Rechnungen so markiert, dass sie nur für Testzwecke dienen dürfen.',
+  'If the test mode is enabled, the Factur-X/ZUGFeRD invoices will be flagged so that they\'re only fit to be used for testing purposes.' => 'Wenn der Testmodus aktiviert ist, werden Factur-X-/ZUGFeRD-Rechnungen so markiert, dass sie nur für Testzwecke dienen dürfen.',
   'If yes, delivery order positions are considered "delivered" only if they have been stocked out of the inventory. Otherwise saving the delivery order is considered delivered.' => 'Wenn diese Option aktiviert ist, gelten Lieferscheinpositionen nur dann als geliefert wenn sie im Lieferschein ausgelagert wurden, und die Ware aus dem Lager ausgebucht wurde. Andernfalls gilt das Speichern des Lieferscheins als Lieferung.',
   'If you enter values for the part number and / or part description then only those bins containing parts whose part number or part description match your input will be shown.' => 'Wenn Sie für die Artikelnummer und / oder die Beschreibung etwas eingeben, so werden nur die Lagerplätze angezeigt, in denen Waren eingelagert sind, die Ihre Suchbegriffe enthalten.',
   'If you have not chosen for example the category revenue for a tax and you choose an revenue account to create a transfer in the general ledger, this tax will not be displayed in the tax dropdown.' => 'Wenn Sie z.B. die Kategory Erlös für eine Steuer nicht gewählt haben und ein Erlöskonto beim Erstellen einer Dialogbuchung wählen, wird diese Steuer auch nicht im Dropdown-Menü für die Steuern angezeigt.',
@@ -1658,8 +1662,8 @@ $self->{texts} = {
   'Import AR from Scanner or Email' => 'Verkaufsbelege importieren vom Scanner oder von Email',
   'Import CSV'                  => 'CSV-Import',
   'Import Status'               => 'Import Status',
+  'Import a Factur-X/ZUGFeRD file:' => 'Eine Factur-X-/ZUGFeRD-Datei importieren',
   'Import a MT940 file:'        => 'Laden Sie eine MT940 Datei hoch:',
-  'Import a ZUGFeRD file:'      => 'Eine ZUGFeRD-Datei importieren',
   'Import all'                  => 'Importiere Alle',
   'Import documents from #1'    => 'Importiere Dateien von Quelle \'#1\'',
   'Import file'                 => 'Import-Datei',
@@ -2044,7 +2048,7 @@ $self->{texts} = {
   'No Journal'                  => 'Kein Journal',
   'No Shopdescription'          => 'Keine Shop-Artikelbeschreibung',
   'No Shopimages'               => 'Keine Shop-Bilder',
-  'No VAT Info for this ZUGFeRD invoice, please ask your vendor to add this for his ZUGFeRD data.' => 'Konnte keine UST-ID für diese ZUGFeRD Rechnungen finden, bitte fragen Sie bei Ihren Lieferanten nach, ob dieses Feld im ZUGFeRD Datensatz gesetzt wird.',
+  'No VAT Info for this Factur-X/ZUGFeRD invoice, please ask your vendor to add this for his Factur-X/ZUGFeRD data.' => 'Konnte keine UST-ID für diese Factur-X-/ZUGFeRD-Rechnungen finden, bitte fragen Sie bei Ihren Lieferanten nach, ob dieses Feld im Factur-X-/ZUGFeRD-Datensatz gesetzt wird.',
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No action defined.'          => 'Keine Aktion definiert.',
   'No article has been selected yet.' => 'Es wurde noch kein Artikel ausgewählt.',
@@ -2053,7 +2057,7 @@ $self->{texts} = {
   'No background job has been created yet.' => 'Es wurden noch keine Hintergrund-Jobs angelegt.',
   'No bank account chosen!'     => 'Kein Bankkonto ausgewählt!',
   'No bank account configured for bank code/BIC #1, account number/IBAN #2.' => 'Kein Bankkonto für BLZ/BIC #1, Kontonummer/IBAN #2 konfiguriert.',
-  'No bank account flagged for ZUGFeRD usage was found.' => 'Es wurde kein Bankkonto gefunden, das für Nutzung mit ZUGFeRD markiert ist.',
+  'No bank account flagged for Factur-X/ZUGFeRD usage was found.' => 'Es wurde kein Bankkonto gefunden, das für Nutzung mit Factur-X/ZUGFeRD markiert ist.',
   'No bank information has been entered in this customer\'s master data entry. You cannot create bank collections unless you enter bank information.' => 'Für diesen Kunden wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Überweisungen für den Lieferanten anlegen.',
   'No bank information has been entered in this vendor\'s master data entry. You cannot create bank transfers unless you enter bank information.' => 'Für diesen Lieferanten wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Überweisungen für den Lieferanten anlegen.',
   'No bins have been added to this warehouse yet.' => 'Es wurden zu diesem Lager noch keine Lagerplätze angelegt.',
@@ -3233,6 +3237,9 @@ $self->{texts} = {
   'The AR transaction #1 has been deleted.' => 'Die Debitorenbuchung #1 wurde gelöscht.',
   'The Bins in Inventory were only a information text field.' => 'Die Lagerplätze unter Stammdaten/Waren sind nur ein informatives Textfeld.',
   'The Bins in master data were only a information text field.' => 'Die Lagerplätze unter Stammdaten/Waren sind nur ein informatives Textfeld.',
+  'The Factur-X/ZUGFeRD XML invoice was not found.' => 'Die Factur-X-/ZUGFeRD-XML-Rechnungsdaten wurden nicht gefunden.',
+  'The Factur-X/ZUGFeRD notes have been saved.' => 'Die Factur-X-/ZUGFeRD-Notizen wurden gespeichert.',
+  'The Factur-X/ZUGFeRD version used is not supported.' => 'Die verwendete Factur-X-/ZUGFeRD-Version wird nicht unterstützt.',
   'The GL transaction #1 has been deleted.' => 'Die Dialogbuchung #1 wurde gelöscht.',
   'The Geierlein path has not been set in the configuration.' => 'Der Geierlein-Pfad wurde in der Konfigurationsdatei nicht gesetzt.',
   'The IBAN \'#1\' is not valid as IBANs in #2 must be exactly #3 characters long.' => 'Die IBAN \'#1\' ist ungültig, da IBANs in #2 genau #3 Zeichen lang sein müssen.',
@@ -3251,11 +3258,8 @@ $self->{texts} = {
   'The VAT ID number in the client configuration is invalid.' => 'Die UStID-Nummer in der Mandantenkonfiguraiton ist ungültig.',
   'The VAT registration number is missing in the client configuration.' => 'Die Umsatzsteuer-ID-Nummer fehlt in der Mandantenkonfiguration.',
   'The WebDAV feature has been used.' => 'Das WebDAV-Feature wurde benutzt.',
-  'The XMP metadata does not declare the ZUGFeRD data.' => 'Die XMP-Metadaten enthalten keine ZUGFeRD-Deklaration.',
-  'The ZUGFeRD XML invoice was not found.' => 'Die ZUGFeRD-XML-Rechnungsdaten wurden nicht gefunden.',
+  'The XMP metadata does not declare the Factur-X/ZUGFeRD data.' => 'Die XMP-Metadaten enthalten keine Factur-X-/ZUGFeRD-Deklaration.',
   'The ZUGFeRD invoice data cannot be generated because the data validation failed.' => 'Die ZUGFeRD-Rechnungsdaten können nicht erzeugt werden, da die Validierung fehlschlug.',
-  'The ZUGFeRD notes have been saved.' => 'Die ZUGFeRD-Notizen wurden gespeichert.',
-  'The ZUGFeRD version used is not supported.' => 'Die verwendete ZUGFeRD-Version wird nicht unterstützt.',
   'The abbreviation is missing.' => 'Abkürzung fehlt',
   'The access rights a user has within a client instance is still governed by his group membership.' => 'Welche Zugriffsrechte ein Benutzer innerhalb eines Mandanten hat, wird weiterhin über Gruppenmitgliedschaften geregelt.',
   'The access rights have been saved.' => 'Die Zugriffsrechte wurden gespeichert.',
@@ -3877,7 +3881,7 @@ $self->{texts} = {
   'Use default warehouse for assembly transfer' => 'Zum Fertigen Standardlager des Bestandteils verwenden',
   'Use existing templates'      => 'Vorhandene Druckvorlagen verwenden',
   'Use fill up when calculating shipped quantities?' => 'Sollen nicht verlinkte Positionen abgeglichen werden?',
-  'Use for ZUGFeRD'             => 'Nutzung mit ZUGFeRD',
+  'Use for Factur-X/ZUGFeRD'    => 'Nutzung mit Factur-X/ZUGFeRD',
   'Use linked items'            => 'Verknüpfte Positionen verwenden',
   'Use master default bin for Default Transfer, if no default bin for the part is configured' => 'Standardlagerplatz für Ein- / Auslagern über Standard-Lagerplatz, falls für die Ware kein expliziter Lagerplatz konfiguriert ist',
   'Use settings from client configuration' => 'Einstellungen aus Mandantenkonfiguration folgen',
@@ -4077,17 +4081,12 @@ $self->{texts} = {
   'Your download does not exist anymore. Please re-run the DATEV export assistant.' => 'Ihr Download existiert nicht mehr. Bitte starten Sie den DATEV-Exportassistenten erneut.',
   'Your import is being processed.' => 'Ihr Import wird verarbeitet',
   'Your target quantity will be added to the stocked quantity.' => 'Ihre gezählte Zielmenge wird zum Lagerbestand hinzugezählt.',
-  'ZUGFeRD import'              => 'ZUGFeRD Import',
-  'ZUGFeRD invoice'             => 'ZUGFeRD-Rechnung',
-  'ZUGFeRD notes for each invoice' => 'ZUGFeRD-Notizen für jede Rechnung',
-  'ZUGFeRD settings'            => 'ZUGFeRD-Einstellungen',
   'Zeitraum'                    => 'Zeitraum',
   'Zero amount posting!'        => 'Buchung ohne Wert',
   'Zip'                         => 'PLZ',
   'Zip, City'                   => 'PLZ, Ort',
   'Zipcode'                     => 'PLZ',
   'Zipcode and city'            => 'PLZ und Stadt',
-  'ZugFeRD Import'              => 'ZUGFeRD Import',
   '[email]'                     => '[email]',
   'absolute'                    => 'absolut',
   'account_description'         => 'Beschreibung',
index f223a1d..f7dd6c9 100644 (file)
     action: YearEndTransactions/form
 - parent: general_ledger
   id: zugferd_import
-  name: ZugFeRD Import
+  name: Factur-X/ZUGFeRD import
   icon: cbob
   order: 485
   access: ap_transactions
     action: edit_sepa_strings
 - parent: system_languages_and_translations
   id: system_languages_and_translations_zugferd_notes
-  name: ZUGFeRD notes for each invoice
+  name: Factur-X/ZUGFeRD notes for each invoice
   order: 450
   module: generictranslations.pl
   params:
index a31dfdb..7c769bc 100644 (file)
@@ -57,8 +57,8 @@
      </rdf:li>
 [% IF zugferd %]
      <rdf:li rdf:parseType="Resource">
-      <pdfaSchema:schema>ZUGFeRD PDFA Extension Schema</pdfaSchema:schema>
-      <pdfaSchema:namespaceURI>urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#</pdfaSchema:namespaceURI>
+      <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>
          <pdfaProperty:name>Version</pdfaProperty:name>
          <pdfaProperty:valueType>Text</pdfaProperty:valueType>
          <pdfaProperty:category>external</pdfaProperty:category>
-         <pdfaProperty:description>The actual version of the ZUGFeRD data</pdfaProperty:description>
+         <pdfaProperty:description>The actual version of the Factur-X/ZUGFeRD data</pdfaProperty:description>
         </rdf:li>
         <rdf:li rdf:parseType="Resource">
          <pdfaProperty:name>ConformanceLevel</pdfaProperty:name>
          <pdfaProperty:valueType>Text</pdfaProperty:valueType>
          <pdfaProperty:category>external</pdfaProperty:category>
-         <pdfaProperty:description>The conformance level of the ZUGFeRD data</pdfaProperty:description>
+         <pdfaProperty:description>The conformance level of the Factur-X/ZUGFeRD data</pdfaProperty:description>
         </rdf:li>
        </rdf:Seq>
       </pdfaSchema:property>
   </rdf:Description>
 
 [% IF zugferd %]
-  <rdf:Description xmlns:fx="urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#"
+  <rdf:Description xmlns:fx="urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#"
                    fx:ConformanceLevel="[% zugferd.conformance_level | xml %]"
                    fx:DocumentFileName="[% zugferd.document_file_name | xml %]"
                    fx:DocumentType="[% zugferd.document_type | xml %]"
index cc31217..ad5f8f7 100644 (file)
   </tr>
   <tr>
   <tr>
-   <td align="right">[% LxERP.t8("Create sales invoices with ZUGFeRD data") %]</td>
-   <td>[% L.select_tag("defaults.create_zugferd_invoices", [ [ 0, LxERP.t8('Do not create ZUGFeRD invoices') ], [ 1, LxERP.t8('Create ZUGFeRD invoices') ], [ 2, LxERP.t8('Create ZUGFeRD invoices in test mode') ] ],
-                       default=SELF.defaults.create_zugferd_invoices) %]</td>
+   <td align="right">[% LxERP.t8("Create sales invoices with Factur-X/ZUGFeRD data") %]</td>
+   <td>[% L.select_tag("defaults.create_zugferd_invoices", SELF.zugferd_settings, default=SELF.defaults.create_zugferd_invoices) %]</td>
    <td>
-     [% LxERP.t8("If enabled ZUGFeRD-conformant sales invoice PDFs will be created.") %]
-     [% LxERP.t8("If the test mode is enabled, the ZUGFeRD invoices will be flagged so that they're only fit to be used for testing purposes.") %]
+     [% LxERP.t8("If enabled Factur-X/ZUGFeRD conformant sales invoice PDFs will be created.") %]
+     [% LxERP.t8("If the test mode is enabled, the Factur-X/ZUGFeRD invoices will be flagged so that they're only fit to be used for testing purposes.") %]
    </td>
   </tr>
 
index 19607d1..260ad85 100644 (file)
@@ -63,7 +63,7 @@
 
 [% IF IS_CUSTOMER %]
    <tr>
-     <th align="right" nowrap>[% LxERP.t8("ZUGFeRD settings") %]</th>
+     <th align="right" nowrap>[% LxERP.t8("Factur-X/ZUGFeRD settings") %]</th>
      <td>[% L.select_tag('create_zugferd_invoices', ZUGFERD_SETTINGS, with_empty = 1) %]</td>
    </tr>
 [% END %]
index 861298a..43e1789 100644 (file)
       <td>
         [% L.checkbox_tag('cv.order_lock', checked = SELF.cv.order_lock, for_submit=1) %]
       </td>
-      <th align="right">[% LxERP.t8("Create sales invoices with ZUGFeRD data") %]</th>
-      <td>[% L.select_tag("cv.create_zugferd_invoices",
-                          [ [ -1, LxERP.t8('Use settings from client configuration') ],
-                            [ 0, LxERP.t8('Do not create ZUGFeRD invoices') ],
-                            [ 1, LxERP.t8('Create ZUGFeRD invoices') ],
-                            [ 2, LxERP.t8('Create ZUGFeRD invoices in test mode') ] ],
-                          default=SELF.cv.create_zugferd_invoices) %]</td>
+      <th align="right">[% LxERP.t8("Create sales invoices with Factur-X/ZUGFeRD data") %]</th>
+      <td>[% L.select_tag("cv.create_zugferd_invoices", SELF.zugferd_settings, default=SELF.cv.create_zugferd_invoices) %]</td>
      </tr>
     [% END %]
   </table>
index 04f1051..5c1ee4e 100644 (file)
@@ -14,7 +14,7 @@
 
    <tr>
     <th class="listheading">&nbsp;</th>
-    <th class="listheading">[% 'ZUGFeRD notes for each invoice' | $T8 %]</th>
+    <th class="listheading">[% 'Factur-X/ZUGFeRD notes for each invoice' | $T8 %]</th>
    </tr>
 
    [%- FOREACH language = LANGUAGES %]
index 21e58fc..0270326 100644 (file)
@@ -32,7 +32,7 @@
   <td>[% P.chart.picker('object.chart_id', SELF.object.chart_id, type='AR_paid,AP_paid', category='A,L,Q', choose=1, style=style, "data-validate"="required", "data-title"=LxERP.t8("Chart")) %]</td>
  </tr>
  <tr>
-  <th align="right">[% LxERP.t8('Use for ZUGFeRD') %]</th>
+  <th align="right">[% LxERP.t8('Use for Factur-X/ZUGFeRD') %]</th>
   <td>[% L.checkbox_tag('object.use_for_zugferd', checked = SELF.object.use_for_zugferd, for_submit=1) %]</td>
  </tr>
  <tr>
index dd8662f..49f88f5 100644 (file)
@@ -6,10 +6,9 @@
  <div class="listtop">[% FORM.title %]</div>
 
  <p>
- [% "Import a ZUGFeRD file:" | $T8 %]
+ [% "Import a Factur-X/ZUGFeRD file:" | $T8 %]
  </p>
 
  <form method="post" action="controller.pl" enctype="multipart/form-data" id="form">
     [% L.input_tag('file', '', type => 'file', accept => '.pdf') %]
  </form>
-