]> wagnertech.de Git - kivitendo-erp.git/commitdiff
ZUGFeRD: Zahlungsinfos ergänzt: Kontonummer, Typ=Einzug/Überweisung
authorMoritz Bunkus <m.bunkus@linet-services.de>
Fri, 6 Mar 2020 14:11:15 +0000 (15:11 +0100)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Fri, 6 Mar 2020 14:11:15 +0000 (15:11 +0100)
SL/Controller/SimpleSystemSetting.pm
SL/DB/Helper/ZUGFeRD.pm
SL/DB/MetaSetup/BankAccount.pm
locale/de/all
sql/Pg-upgrade2/bank_account_flag_for_zugferd_usage.sql [new file with mode: 0644]
templates/webpages/simple_system_setting/_bank_account_form.html

index 2e559a31d8469e2cdfa6fa9557389ab45fc5d502..4fec19a9f7b2c23591b5db6b7ab3d19f25dee2aa 100644 (file)
@@ -35,6 +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') } },
       { method => 'reconciliation_starting_date_as_date',      title => t8('Date'),    align => 'right' },
       { method => 'reconciliation_starting_balance_as_number', title => t8('Balance'), align => 'right' },
     ],
index 3ad825c743f99616bbc7f31f2313ddceaacd2b40..0511256776d2cc7f0fda39617771a1a10edd6f84 100644 (file)
@@ -6,6 +6,7 @@ use utf8;
 use parent qw(Exporter);
 our @EXPORT = qw(create_zugferd_data create_zugferd_xmp_data);
 
+use SL::DB::BankAccount;
 use SL::DB::GenericTranslation;
 use SL::DB::Tax;
 use SL::DB::TaxKey;
@@ -176,6 +177,28 @@ sub _line_item {
   # <ram:IncludedSupplyChainTradeLineItem>
 }
 
+sub _specified_trade_settlement_payment_means {
+  my ($self, %params) = @_;
+
+  #     <ram:SpecifiedTradeSettlementPaymentMeans>
+  $params{xml}->startTag('ram:SpecifiedTradeSettlementPaymentMeans');
+  $params{xml}->dataElement('ram:TypeCode', $self->direct_debit ? 59 : 58); # 59 = SEPA direct debit, 58 = SEPA credit transfer
+
+  if ($self->direct_debit) {
+    $params{xml}->startTag('ram:PayerPartyDebtorFinancialAccount');
+    $params{xml}->dataElement('ram:IBANID', $self->customer->iban);
+    $params{xml}->endTag;
+
+  } else {
+    $params{xml}->startTag('ram:PayeePartyCreditorFinancialAccount');
+    $params{xml}->dataElement('ram:IBANID', $params{bank_account}->iban);
+    $params{xml}->endTag;
+  }
+
+  $params{xml}->endTag;
+  #     </ram:SpecifiedTradeSettlementPaymentMeans>
+}
+
 sub _taxes {
   my ($self, %params) = @_;
 
@@ -520,6 +543,7 @@ sub _applicable_header_trade_settlement {
   $params{xml}->startTag("ram:ApplicableHeaderTradeSettlement");
   $params{xml}->dataElement("ram:InvoiceCurrencyCode", _u8(SL::Helper::ISO4217::map_currency_name_to_code($self->currency->name) // 'EUR'));
 
+  _specified_trade_settlement_payment_means($self, %params);
   _taxes($self, %params);
   _payment_terms($self, %params);
   _totals($self, %params);
@@ -546,6 +570,7 @@ sub _supply_chain_trade_transaction {
 sub _validate_data {
   my ($self) = @_;
 
+  my %result;
   my $prefix = $::locale->text('The ZUGFeRD invoice data cannot be generated because the data validation failed.') . ' ';
 
   if (!$::instance_conf->get_co_ustid) {
@@ -572,43 +597,54 @@ sub _validate_data {
   if ($failed_unit) {
     SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('One of the units used (#1) cannot be mapped to a known unit code from the UN/ECE Recommendation 20 list.', $failed_unit));
   }
+
+  if ($self->direct_debit) {
+    if (!$self->customer->iban) {
+      SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('The customer\'s bank account number (IBAN) is missing.'));
+    }
+
+  } else {
+    my $bank_accounts     = SL::DB::Manager::BankAccount->get_all;
+    $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.'));
+    }
+  }
+
+  return %result;
 }
 
 sub create_zugferd_data {
-  my ($self) = @_;
+  my ($self)        = @_;
 
-  _validate_data($self);
+  my $output        = '';
 
-  my %ptc_data = $self->calculate_prices_and_taxes;
-  my $output   = '';
-  my $xml      = XML::Writer->new(
-    OUTPUT      => \$output,
-    DATA_MODE   => 1,
-    DATA_INDENT => 2,
-    ENCODING    => 'utf-8',
+  my %params        = _validate_data($self);
+  $params{ptc_data} = { $self->calculate_prices_and_taxes };
+  $params{xml}      = XML::Writer->new(
+    OUTPUT          => \$output,
+    DATA_MODE       => 1,
+    DATA_INDENT     => 2,
+    ENCODING        => 'utf-8',
   );
 
-  my %params = (
-    ptc_data => \%ptc_data,
-    xml      => $xml,
-  );
-
-  $xml->xmlDecl();
+  $params{xml}->xmlDecl();
 
   # <rsm:CrossIndustryInvoice>
-  $xml->startTag("rsm:CrossIndustryInvoice",
-                 "xmlns:a"   => "urn:un:unece:uncefact:data:standard:QualifiedDataType:100",
-                 "xmlns:rsm" => "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100",
-                 "xmlns:qdt" => "urn:un:unece:uncefact:data:standard:QualifiedDataType:10",
-                 "xmlns:ram" => "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100",
-                 "xmlns:xs"  => "http://www.w3.org/2001/XMLSchema",
-                 "xmlns:udt" => "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100");
+  $params{xml}->startTag("rsm:CrossIndustryInvoice",
+                         "xmlns:a"   => "urn:un:unece:uncefact:data:standard:QualifiedDataType:100",
+                         "xmlns:rsm" => "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100",
+                         "xmlns:qdt" => "urn:un:unece:uncefact:data:standard:QualifiedDataType:10",
+                         "xmlns:ram" => "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100",
+                         "xmlns:xs"  => "http://www.w3.org/2001/XMLSchema",
+                         "xmlns:udt" => "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100");
 
   _exchanged_document_context($self, %params);
   _exchanged_document($self, %params);
   _supply_chain_trade_transaction($self, %params);
 
-  $xml->endTag;
+  $params{xml}->endTag;
   # </rsm:CrossIndustryInvoice>
 
   return $output;
index b72a170b4d3f47bd1c1aab2837aaaa4197495c92..cd3ffce45d7f97f9aca406d4de388df00ddc8eb3 100644 (file)
@@ -21,6 +21,7 @@ __PACKAGE__->meta->columns(
   reconciliation_starting_balance => { type => 'numeric', precision => 15, scale => 5 },
   reconciliation_starting_date    => { type => 'date' },
   sortkey                         => { type => 'integer', not_null => 1 },
+  use_for_zugferd                 => { type => 'boolean', not_null => 1 },
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
index 43959b9db7c94fbe73752403825e4a4f33571753..72f7aa969ac9e1749770591c6e086b8a3b72827c 100755 (executable)
@@ -2005,6 +2005,7 @@ $self->{texts} = {
   'No assembly has been selected yet.' => 'Es wurde noch kein Erzeugnis ausgewahlt.',
   '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 flagged for ZUGFeRD usage was found.' => 'Es wurde kein Bankkonto gefunden, das für Nutzung mit 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.',
@@ -3272,6 +3273,7 @@ $self->{texts} = {
   'The custom variable has been saved.' => 'Die benutzerdefinierte Variable wurde gespeichert.',
   'The custom variable is in use and cannot be deleted.' => 'Die benutzerdefinierte Variable ist in Benutzung und kann nicht gelöscht werden.',
   'The customer name is missing.' => 'Der Kundenname fehlt.',
+  'The customer\'s bank account number (IBAN) is missing.' => 'Die Kontonummer (IBAN) des Kunden fehlt.',
   'The database for user management and authentication does not exist. You can create let kivitendo create it with the following parameters:' => 'Die Datenbank für die Benutzeranmeldung existiert nicht. Sie können Sie von kivitendo automatisch mit den folgenden Parametern anlegen lassen:',
   'The database host is missing.' => 'Der Datenbankhost fehlt.',
   'The database name is missing.' => 'Der Datenbankname fehlt.',
@@ -3808,6 +3810,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 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',
diff --git a/sql/Pg-upgrade2/bank_account_flag_for_zugferd_usage.sql b/sql/Pg-upgrade2/bank_account_flag_for_zugferd_usage.sql
new file mode 100644 (file)
index 0000000..d62d7ee
--- /dev/null
@@ -0,0 +1,14 @@
+-- @tag: bank_account_flag_for_zugferd_usage
+-- @description: Bankkonto für die Nutzung mit ZUGFeRD markieren
+-- @depends: release_3_5_5
+ALTER TABLE bank_accounts
+ADD COLUMN use_for_zugferd BOOLEAN;
+
+UPDATE bank_accounts
+SET use_for_zugferd = (
+  SELECT COUNT(*)
+  FROM bank_accounts
+) = 1;
+
+ALTER TABLE bank_accounts
+ALTER COLUMN use_for_zugferd SET NOT NULL;
index f3da6cc207254d9371c57a4a0b86b2a005fd788e..21e58fcffb369e12f27840f346817d5c141a3e55 100644 (file)
   <th align="right">[% LxERP.t8('Chart') %]</th>
   <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>
+  <td>[% L.checkbox_tag('object.use_for_zugferd', checked = SELF.object.use_for_zugferd, for_submit=1) %]</td>
+ </tr>
  <tr>
   <th align="right">[% LxERP.t8('Obsolete') %]</th>
   <td>[% L.checkbox_tag('object.obsolete', checked = SELF.object.obsolete, for_submit=1) %]</td>