]> wagnertech.de Git - kivitendo-erp.git/commitdiff
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 9bf0eda3e3cbe3dad658a77043832b0f2a75c691..12125122e749723d398f5ce9655ebaa5033cf429 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::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
 
 __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) ],
 );
                                   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_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           },
 
 sub init_posting_options {
   [ { title => t8("never"),           value => 0           },
index 8b10f2ca3c5ad3dd4c7bc11826662dfea6cbdb0c..e8f1c5a4a0e7e2729524d00ae4c225ef6e7ab311 100644 (file)
@@ -11,6 +11,7 @@ use SL::Helper::Flash;
 use SL::Locale::String;
 use SL::Util qw(trim);
 use SL::Webdav;
 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;
 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 (
 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
 );
 
 # 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) = @_;
 
 sub _new_customer_vendor_object {
   my ($self) = @_;
 
index aaca8e9bd531cbbe331f5dcdf9a0d088d3a8d551..f8dd4bc494b745fec6995b6ddec90abeca756be8 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'), },
       { 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' },
     ],
       { method => 'reconciliation_starting_date_as_date',      title => t8('Date'),    align => 'right' },
       { method => 'reconciliation_starting_balance_as_number', title => t8('Balance'), align => 'right' },
     ],
index 29d7e074cfabb80a5f166a8a262953310f8c3595..cad98a363523c06ee4cc1263b07b45a78a35204f 100644 (file)
@@ -17,7 +17,7 @@ sub action_upload_zugferd {
   my ($self, %params) = @_;
 
   $self->setup_zugferd_action_bar;
   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 {
 }
 
 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});
   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;
   }
   # 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);
 
 
   $ustid = SL::VATIDNr->normalize($ustid);
 
index 1e1e17258c761fc577447df32e7232248b23e010..467d4c11ad238c327f5c41a63f42271bb783e122 100644 (file)
@@ -58,7 +58,7 @@ sub create_pdf_a_print_options {
       },
       zugferd              => {
         conformance_level  => 'EXTENDED',
       },
       zugferd              => {
         conformance_level  => 'EXTENDED',
-        document_file_name => 'ZUGFeRD-invoice.xml',
+        document_file_name => 'factur-x.xml',
         document_type      => 'INVOICE',
         version            => '1.0',
       },
         document_type      => 'INVOICE',
         version            => '1.0',
       },
index 5455398cd9c948464521d1c0b1bf07474e93eba9..017bbc535ae266833ad447c1412fec4560b83ea8 100644 (file)
@@ -14,6 +14,7 @@ use SL::Helper::ISO3166;
 use SL::Helper::ISO4217;
 use SL::Helper::UNECERecommendation20;
 use SL::VATIDNr;
 use SL::Helper::ISO4217;
 use SL::Helper::UNECERecommendation20;
 use SL::VATIDNr;
+use SL::ZUGFeRD qw(:PROFILES);
 
 use Carp;
 use Encode qw(encode);
 
 use Carp;
 use Encode qw(encode);
@@ -24,6 +25,13 @@ use XML::Writer;
 
 my @line_names = qw(LineOne LineTwo LineThree);
 
 
 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 // '');
 sub _u8 {
   my ($value) = @_;
   return encode('UTF-8', $value // '');
@@ -340,14 +348,14 @@ sub _exchanged_document_context {
   #   <rsm:ExchangedDocumentContext>
   $params{xml}->startTag("rsm:ExchangedDocumentContext");
 
   #   <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}->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>
   $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}) {
     $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)        = @_;
 
 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        = '';
 
 
   my $output        = '';
 
@@ -655,7 +668,7 @@ sub create_zugferd_xmp_data {
 
   return {
     conformance_level  => 'EXTENDED',
 
   return {
     conformance_level  => 'EXTENDED',
-    document_file_name => 'ZUGFeRD-invoice.xml',
+    document_file_name => 'factur-x.xml',
     document_type      => 'INVOICE',
     version            => '1.0',
   };
     document_type      => 'INVOICE',
     version            => '1.0',
   };
index cedbb49bc57e363cc1ffad38be23b47c13403268..06fb81918034af9cc8fcbb8624bae51be3b4c4db 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,
     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',
       }
         relationship => '/Alternative',
         mime_type    => 'text/xml',
       }
index b2b6838abc3480c38c20a39c6fb5231fb01167f7..bc03eb3bb06cd90c60bba71d97b43806e4901796 100644 (file)
@@ -394,8 +394,8 @@ sub _embed_file_directive {
   my ($self, $file) = @_;
 
   # { source      => $xmlfile,
   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;
 
   my $file_name  =  blessed($file->{source}) && $file->{source}->can('filename') ? $file->{source}->filename : "" . $file->{source}->filename;
   my $embed_name =  $file->{name} // $file_name;
index 780122c43f43dd21a53a79f4d66ca7a16fea7a9b..02d73de30b331c45ed7d6468048283a8460001a8 100644 (file)
@@ -9,6 +9,15 @@ use Data::Dumper;
 use List::Util qw(first);
 use XML::LibXML;
 
 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;
 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;
 
 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 {};
 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}) {
     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;
     }
 
       last;
     }
 
-    if ($ns->getData =~ m{zugferd}i) {
+    if ($ns->getData =~ m{zugferd|factur-x}i) {
       $zugferd_version = 'unsupported';
       last;
     }
       $zugferd_version = 'unsupported';
       last;
     }
@@ -122,14 +153,14 @@ sub extract_from_pdf {
   if (!$zugferd_version) {
     return {
       result  => RES_ERR_NOT_ZUGFERD(),
   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(),
     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(),
   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
 
 
 =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
 
 
 =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>
 
 
 =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
 
 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
 
 =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
 
 =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 e8c6efd54ed4c389876d383355a1eb7f6788bc6d..87eb0d8f64172a974aab7efcefb191224906caee 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::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";
 
 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') ],
 
 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 {
 }
 
 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('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});
 
   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'), },
     '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,
   );
 
     %column_defs_cvars,
   );
 
index 3481fca960cd2c5b688f54dbc4f693845d046205..4e6d263288d0a11f3b3e670926d0653ac23d1a50 100644 (file)
@@ -227,7 +227,7 @@ sub edit_zugferd_notes {
 
   setup_generictranslations_edit_zugferd_notes_action_bar();
 
 
   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');
 }
   $::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();
 }
 
   edit_zugferd_notes();
 }
index 0362e13ae114104f4945a7a8925dc1726dc01b84..3f43c15c845bb959fb42e4552015e2e3fe332e95 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,
     $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',
       }
         relationship => '/Alternative',
         mime_type    => 'text/xml',
       }
index 90fc6e565b5a6e853c59f50a8e40d615815e6107..11f0d4eb72be7bad1f652025046f6828512621ed 100644 (file)
@@ -7261,7 +7261,7 @@ document_path = /var/local/kivi_documents
                        </orderedlist>
 
                        <para>Wenn diese Voraussetzungen erfüllt sind, kann die Rechnung
                        </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
                        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 789c953ca7daec429cc1b958d4c67ad20162a7bf..bcbbe31a43d651071047dd109921f085824c4ce0 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',
   '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"',
   '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 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',
   '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 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 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',
   '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',
   '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',
   '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 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',
   '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 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',
   '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',
   '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',
   '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 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).',
   '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 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.',
   '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 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 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',
   '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 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.',
   '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 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.',
   '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 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.',
   '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 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 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.',
   '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 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',
   '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.',
   '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',
   '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',
   '[email]'                     => '[email]',
   'absolute'                    => 'absolut',
   'account_description'         => 'Beschreibung',
index f223a1d40429a36ca4df53450c162474e4d7e5bc..f7dd6c95c7e6d8b42588be07d82e49ddc44ad4ff 100644 (file)
     action: YearEndTransactions/form
 - parent: general_ledger
   id: zugferd_import
     action: YearEndTransactions/form
 - parent: general_ledger
   id: zugferd_import
-  name: ZugFeRD Import
+  name: Factur-X/ZUGFeRD import
   icon: cbob
   order: 485
   access: ap_transactions
   icon: cbob
   order: 485
   access: ap_transactions
     action: edit_sepa_strings
 - parent: system_languages_and_translations
   id: system_languages_and_translations_zugferd_notes
     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:
   order: 450
   module: generictranslations.pl
   params:
index a31dfdb167a16158bf34372f2568bed0ba9a39e5..7c769bcd65552e20339480a133ee7745efa98dee 100644 (file)
@@ -57,8 +57,8 @@
      </rdf:li>
 [% IF zugferd %]
      <rdf:li rdf:parseType="Resource">
      </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>
       <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: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>
         </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:li>
        </rdf:Seq>
       </pdfaSchema:property>
   </rdf:Description>
 
 [% IF zugferd %]
   </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 %]"
                    fx:ConformanceLevel="[% zugferd.conformance_level | xml %]"
                    fx:DocumentFileName="[% zugferd.document_file_name | xml %]"
                    fx:DocumentType="[% zugferd.document_type | xml %]"
index cc31217c7b3f96e54cb1e33f72a67ba93d31ca03..ad5f8f72295126462dbddf553d7a8e13d3e69e62 100644 (file)
   </tr>
   <tr>
   <tr>
   </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>
    <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>
 
    </td>
   </tr>
 
index 19607d17a1be511a88f8178e239457716611c2d2..260ad85e952367ec197256690c1c157ede31f4d5 100644 (file)
@@ -63,7 +63,7 @@
 
 [% IF IS_CUSTOMER %]
    <tr>
 
 [% 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 %]
      <td>[% L.select_tag('create_zugferd_invoices', ZUGFERD_SETTINGS, with_empty = 1) %]</td>
    </tr>
 [% END %]
index 861298aa60b8b6cc95a2f2b95e73960cd9dc5059..43e1789e995d9efb838b62c0d0f2a2bf3f659063 100644 (file)
       <td>
         [% L.checkbox_tag('cv.order_lock', checked = SELF.cv.order_lock, for_submit=1) %]
       </td>
       <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>
      </tr>
     [% END %]
   </table>
index 04f1051f0f41b8f90b6f6124aee3bc7682bdd816..5c1ee4e058e04ea023c2599a73152352dd34e2be 100644 (file)
@@ -14,7 +14,7 @@
 
    <tr>
     <th class="listheading">&nbsp;</th>
 
    <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 %]
    </tr>
 
    [%- FOREACH language = LANGUAGES %]
index 21e58fcffb369e12f27840f346817d5c141a3e55..0270326f9cba331637633ed4ba5981b60298f345 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>
   <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>
   <td>[% L.checkbox_tag('object.use_for_zugferd', checked = SELF.object.use_for_zugferd, for_submit=1) %]</td>
  </tr>
  <tr>
index dd8662fd39c66c5e7ceaa934246833d63d471809..49f88f54c4100b29a57ad1b6da1e52565aea0842 100644 (file)
@@ -6,10 +6,9 @@
  <div class="listtop">[% FORM.title %]</div>
 
  <p>
  <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>
  </p>
 
  <form method="post" action="controller.pl" enctype="multipart/form-data" id="form">
     [% L.input_tag('file', '', type => 'file', accept => '.pdf') %]
  </form>
-