From 88d162cc5e8e8d3810059d918a1eef6a2b205984 Mon Sep 17 00:00:00 2001
From: "Martin Helmling martin.helmling@octosoft.eu"
Date: Mon, 7 Nov 2016 08:26:11 +0100
Subject: [PATCH] =?utf8?q?Bankimport:=20Behandlung=20von=20Sammel=C3=BCber?=
=?utf8?q?weisungen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit
Generell werden die SEPA Export-Items aus der Punktebewertung herausgenommn,
dafür wird eine exaktere Prüfung auch mittels des Transaktionstyps ermittelt.
Dadurch werden auch Sammellastschriften/Ãberweisungen erkannt.
Setzen von Skontotyp, kein Prüfen der Sepaitems mehr in >get_agreement_with_invoice
---
SL/Controller/BankTransaction.pm | 216 ++++++++++++------
SL/Controller/CsvImport/BankTransaction.pm | 33 +--
SL/DB/BankTransaction.pm | 43 ++--
SL/DB/Helper/Payment.pm | 7 +-
SL/SEPA.pm | 5 +-
locale/de/all | 2 +
.../webpages/bank_transactions/list.html | 27 +--
.../webpages/bank_transactions/tabs/all.html | 13 +-
.../bank_transactions/tabs/automatic.html | 30 ++-
9 files changed, 234 insertions(+), 142 deletions(-)
diff --git a/SL/Controller/BankTransaction.pm b/SL/Controller/BankTransaction.pm
index 68047f314..350ce610f 100644
--- a/SL/Controller/BankTransaction.pm
+++ b/SL/Controller/BankTransaction.pm
@@ -23,6 +23,7 @@ use SL::DB::AccTransaction;
use SL::DB::Tax;
use SL::DB::Draft;
use SL::DB::BankAccount;
+use SL::DB::SepaExportItem;
use SL::DBUtils qw(like);
use SL::Presenter;
@@ -97,23 +98,100 @@ sub action_list {
@where
],
);
+ $main::lxdebug->message(LXDebug->DEBUG2(),"count bt=".scalar(@{$bank_transactions}." bank_account=".$bank_account->id." chart=".$bank_account->chart_id));
- my $all_open_ar_invoices = SL::DB::Manager::Invoice ->get_all(where => [amount => { gt => \'paid' }], with_objects => 'customer');
- my $all_open_ap_invoices = SL::DB::Manager::PurchaseInvoice->get_all(where => [amount => { gt => \'paid' }], with_objects => 'vendor');
+ my $all_open_ar_invoices = SL::DB::Manager::Invoice ->get_all(where => [amount => { gt => \'paid' }], with_objects => ['customer','payment_terms']);
+ my $all_open_ap_invoices = SL::DB::Manager::PurchaseInvoice->get_all(where => [amount => { gt => \'paid' }], with_objects => ['vendor' ,'payment_terms']);
+ my $all_open_sepa_export_items = SL::DB::Manager::SepaExportItem->get_all(where => [chart_id => $bank_account->chart_id ,
+ 'sepa_export.executed' => 0, 'sepa_export.closed' => 0 ], with_objects => ['sepa_export']);
+ $main::lxdebug->message(LXDebug->DEBUG2(),"count sepaexport=".scalar(@{$all_open_sepa_export_items}));
my @all_open_invoices;
# filter out invoices with less than 1 cent outstanding
push @all_open_invoices, grep { abs($_->amount - $_->paid) >= 0.01 } @{ $all_open_ar_invoices };
push @all_open_invoices, grep { abs($_->amount - $_->paid) >= 0.01 } @{ $all_open_ap_invoices };
+ $main::lxdebug->message(LXDebug->DEBUG2(),"bank_account=".$::form->{filter}{bank_account}." invoices: ".scalar(@{ $all_open_ar_invoices }).
+ " + ".scalar(@{ $all_open_ap_invoices })." transactions=".scalar(@{ $bank_transactions }));
+
+ my @all_sepa_invoices;
+ my @all_non_sepa_invoices;
+ my %sepa_exports;
+ # first collect sepa export items to open invoices
+ foreach my $open_invoice (@all_open_invoices){
+ # my @items = grep { $_->ap_id == $open_invoice->id || $_->ar_id == $open_invoice->id } @{$all_open_sepa_export_items};
+ $open_invoice->{realamount} = $::form->format_amount(\%::myconfig,$open_invoice->amount,2);
+ $open_invoice->{skonto_type} = 'without_skonto';
+ foreach ( @{$all_open_sepa_export_items}) {
+ if ( $_->ap_id == $open_invoice->id || $_->ar_id == $open_invoice->id ) {
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"exitem=".$_->id." for invoice ".$open_invoice->id);
+ $open_invoice->{sepa_export_item} = $_ ;
+ $open_invoice->{skonto_type} = $_->payment_type;
+ $sepa_exports{$_->sepa_export_id} ||= { count => 0, is_ar => 0, amount => 0, proposed => 0, invoices => [], item => $_ };
+ $sepa_exports{$_->sepa_export_id}->{count}++ ;
+ $sepa_exports{$_->sepa_export_id}->{is_ar}++ if $_->ar_id == $open_invoice->id;
+ $sepa_exports{$_->sepa_export_id}->{amount} += $_->amount;
+ push ( @{ $sepa_exports{$_->sepa_export_id}->{invoices}} , $open_invoice );
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"amount for export id ".$_->sepa_export_id." = ".
+ # $sepa_exports{$_->sepa_export_id}->{amount}." count = ".
+ # $sepa_exports{$_->sepa_export_id}->{count}." is_ar = ".
+ # $sepa_exports{$_->sepa_export_id}->{is_ar} );
+ push @all_sepa_invoices , $open_invoice;
+ }
+ }
+ push @all_non_sepa_invoices , $open_invoice if ! $open_invoice->{sepa_export_item};
+ }
# try to match each bank_transaction with each of the possible open invoices
# by awarding points
+ @all_open_invoices = @all_non_sepa_invoices;
+ my @proposals;
foreach my $bt (@{ $bank_transactions }) {
- next unless $bt->{remote_name}; # bank has no name, usually fees, use create invoice to assign
+ ## 5 Stellen hinter dem Komma auf 2 Stellen reduzieren
+ $bt->amount($bt->amount*1);
+ $bt->invoice_amount($bt->invoice_amount*1);
+ $main::lxdebug->message(LXDebug->DEBUG2(),"BT ".$bt->id." amount=".$bt->amount." invoice_amount=".$bt->invoice_amount." remote=". $bt->{remote_name});
+
+ $bt->{proposals} = [];
$bt->{remote_name} .= $bt->{remote_name_1} if $bt->{remote_name_1};
+ if ( $self->is_collective_transaction($bt) ) {
+ foreach ( keys %sepa_exports) {
+ my $factor = ($sepa_exports{$_}->{is_ar}>0?1:-1);
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"Exp ID=".$_." factor=".$factor." compare sum amount ".($sepa_exports{$_}->{amount} *1) ." == ".($bt->amount * $factor));
+ if ( $bt->transactioncode eq '191' && ($sepa_exports{$_}->{amount} * 1) eq ($bt->amount * $factor) ) {
+ ## jupp
+ $bt->{proposals} = $sepa_exports{$_}->{invoices} ;
+ $sepa_exports{$_}->{proposed}=1;
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"has ".scalar($bt->{proposals})." invoices");
+ push(@proposals, $bt);
+ next;
+ }
+ }
+ }
+ next unless $bt->{remote_name}; # bank has no name, usually fees, use create invoice to assign
+
+ foreach ( keys %sepa_exports) {
+ my $factor = ($sepa_exports{$_}->{is_ar}>0?1:-1);
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"exp count=".$sepa_exports{$_}->{count}." factor=".$factor." proposed=".$sepa_exports{$_}->{proposed});
+ if ( $sepa_exports{$_}->{count} == 1 ) {
+ my $oinvoice = @{ $sepa_exports{$_}->{invoices}}[0];
+ my $eitem = $sepa_exports{$_}->{item};
+ $eitem->amount($eitem->amount*1);
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"remote account '".$bt->{remote_account_number}."' bt_amount=". ($bt->amount * $factor));
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"compare with '".$eitem->vc_iban."' amount=".$eitem->amount);
+ if ( $bt->{remote_account_number} eq $eitem->vc_iban && $eitem->amount eq ($bt->amount * $factor)) {
+ ## jupp
+ $bt->{proposals} = $sepa_exports{$_}->{invoices} ;
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"found invoice");
+ $sepa_exports{$_}->{proposed}=1;
+ push(@proposals, $bt);
+ next;
+ }
+ }
+ }
+
# try to match the current $bt to each of the open_invoices, saving the
# results of get_agreement_with_invoice in $open_invoice->{agreement} and
# $open_invoice->{rule_matches}.
@@ -125,10 +203,9 @@ sub action_list {
foreach my $open_invoice (@all_open_invoices){
($open_invoice->{agreement}, $open_invoice->{rule_matches}) = $bt->get_agreement_with_invoice($open_invoice);
+ # $main::lxdebug->message(LXDebug->DEBUG2(),"agreement=".$open_invoice->{agreement}." rules matches=".$open_invoice->{rule_matches});
};
- $bt->{proposals} = [];
-
my $agreement = 15;
my $min_agreement = 3; # suggestions must have at least this score
@@ -153,13 +230,15 @@ sub action_list {
# * there must be only one exact match
# * depending on whether sales or purchase the amount has to have the correct sign (so Gutschriften don't work?)
my $proposal_threshold = 5;
- my @proposals = grep {
+ my @otherproposals = grep {
($_->{agreement} >= $proposal_threshold)
&& (1 == scalar @{ $_->{proposals} })
&& (@{ $_->{proposals} }[0]->is_sales ? abs(@{ $_->{proposals} }[0]->amount - $_->amount) < 0.01
: abs(@{ $_->{proposals} }[0]->amount + $_->amount) < 0.01)
} @{ $bank_transactions };
+ push ( @proposals, @otherproposals);
+
# sort bank transaction proposals by quality (score) of proposal
$bank_transactions = [ sort { $a->{agreement} <=> $b->{agreement} } @{ $bank_transactions } ] if $::form->{sort_by} eq 'proposal' and $::form->{sort_dir} == 1;
$bank_transactions = [ sort { $b->{agreement} <=> $a->{agreement} } @{ $bank_transactions } ] if $::form->{sort_by} eq 'proposal' and $::form->{sort_dir} == 0;
@@ -169,7 +248,9 @@ sub action_list {
title => t8('Bank transactions MT940'),
BANK_TRANSACTIONS => $bank_transactions,
PROPOSALS => \@proposals,
- bank_account => $bank_account );
+ bank_account => $bank_account,
+ ui_tab => scalar(@proposals) > 0?1:0,
+ );
}
sub action_assign_invoice {
@@ -373,10 +454,12 @@ sub action_ajax_accept_invoices {
);
}
-sub action_save_invoices {
+sub save_invoices {
my ($self) = @_;
- my $invoice_hash = delete $::form->{invoice_ids}; # each key (the bt line with a bt_id) contains an array of invoice_ids
+ return 0 if !$::form->{invoice_ids};
+
+ my %invoice_hash = %{ delete $::form->{invoice_ids} }; # each key (the bt line with a bt_id) contains an array of invoice_ids
# e.g. three partial payments with bt_ids 54, 55 and 56 for invoice with id 74:
# $invoice_hash = {
@@ -403,16 +486,58 @@ sub action_save_invoices {
$self->problems([]);
- while ( my ($bank_transaction_id, $invoice_ids) = each(%$invoice_hash) ) {
- push @{ $self->problems }, $self->save_single_bank_transaction(
- bank_transaction_id => $bank_transaction_id,
- invoice_ids => $invoice_ids,
- );
+ my $count = 0;
+
+ if ( $::form->{proposal_ids} ) {
+ foreach (@{ $::form->{proposal_ids} }) {
+ my $bank_transaction_id = $_;
+ my $invoice_ids = $invoice_hash{$_};
+ push @{ $self->problems }, $self->save_single_bank_transaction(
+ bank_transaction_id => $bank_transaction_id,
+ invoice_ids => $invoice_ids,
+ );
+ $count += scalar( @{$invoice_ids} );
+ }
+ } else {
+ while ( my ($bank_transaction_id, $invoice_ids) = each(%invoice_hash) ) {
+ push @{ $self->problems }, $self->save_single_bank_transaction(
+ bank_transaction_id => $bank_transaction_id,
+ invoice_ids => $invoice_ids,
+ );
+ $count += scalar( @{$invoice_ids} );
+ }
}
+ return $count;
+}
+
+sub action_save_invoices {
+ my ($self) = @_;
+ my $count = $self->save_invoices();
+
+ flash('ok', t8('#1 invoice(s) saved.', $count));
$self->action_list();
}
+sub action_save_proposals {
+ my ($self) = @_;
+ if ( $::form->{proposal_ids} ) {
+ my $propcount = scalar(@{ $::form->{proposal_ids} });
+ if ( $propcount > 0 ) {
+ my $count = $self->save_invoices();
+
+ flash('ok', t8('#1 proposal(s) with #2 invoice(s) saved.', $propcount, $count));
+ }
+ }
+ $self->action_list();
+
+}
+
+sub is_collective_transaction {
+ my ($self, $bt) = @_;
+ return $bt->transactioncode eq "191";
+}
+
sub save_single_bank_transaction {
my ($self, %params) = @_;
@@ -509,18 +634,19 @@ sub save_single_bank_transaction {
# pay invoice or go to the next bank transaction if the amount is not sufficiently high
if ($invoice->open_amount <= $amount_of_transaction && $n_invoices < $max_invoices) {
+ my $open_amount = ($payment_type eq 'with_skonto_pt'?$invoice->amount_less_skonto:$invoice->open_amount);
# first calculate new bank transaction amount ...
if ($invoice->is_sales) {
- $amount_of_transaction -= $sign * $invoice->open_amount;
- $bank_transaction->invoice_amount($bank_transaction->invoice_amount + $invoice->open_amount);
+ $amount_of_transaction -= $sign * $open_amount;
+ $bank_transaction->invoice_amount($bank_transaction->invoice_amount + $open_amount);
} else {
- $amount_of_transaction += $sign * $invoice->open_amount;
- $bank_transaction->invoice_amount($bank_transaction->invoice_amount - $invoice->open_amount);
+ $amount_of_transaction += $sign * $open_amount;
+ $bank_transaction->invoice_amount($bank_transaction->invoice_amount - $open_amount);
}
# ... and then pay the invoice
$invoice->pay_invoice(chart_id => $bank_transaction->local_bank_account->chart_id,
trans_id => $invoice->id,
- amount => $invoice->open_amount,
+ amount => $open_amount,
payment_type => $payment_type,
transdate => $bank_transaction->transdate->to_kivitendo);
} else { # use the whole amount of the bank transaction for the invoice, overpay the invoice if necessary
@@ -590,58 +716,6 @@ sub save_single_bank_transaction {
return grep { $_ } ($error, @warnings);
}
-sub action_save_proposals {
- my ($self) = @_;
-
- foreach my $bt_id (@{ $::form->{proposal_ids} }) {
- my $bt = SL::DB::Manager::BankTransaction->find_by(id => $bt_id);
-
- my $arap = SL::DB::Manager::Invoice->find_by(id => $::form->{"proposed_invoice_$bt_id"});
- $arap = SL::DB::Manager::PurchaseInvoice->find_by(id => $::form->{"proposed_invoice_$bt_id"}) if not defined $arap;
-
- # check for existing record_link for that $bt and $arap
- # do this before any changes to $bt are made
- die t8("Bank transaction with id #1 has already been linked to #2.", $bt->id, $arap->displayable_name)
- if _existing_record_link($bt, $arap);
-
- #mark bt as booked
- $bt->invoice_amount($bt->amount);
- $bt->save;
-
- #pay invoice
- $arap->pay_invoice(chart_id => $bt->local_bank_account->chart_id,
- trans_id => $arap->id,
- amount => $arap->amount,
- transdate => $bt->transdate->to_kivitendo);
- $arap->save;
-
- #create record link
- my @props = (
- from_table => 'bank_transactions',
- from_id => $bt_id,
- to_table => $arap->is_sales ? 'ar' : 'ap',
- to_id => $arap->id,
- );
-
- SL::DB::RecordLink->new(@props)->save;
-
- # code duplicated in action_save_invoices!
- # "close" a sepa_export_item if it exists
- # currently only works, if there is only exactly one open sepa_export_item
- if ( my $seis = $arap->find_sepa_export_items({ executed => 0 }) ) {
- if ( scalar @$seis == 1 ) {
- # moved the execution and the check for sepa_export into a method,
- # this isn't part of a transaction, though
- $seis->[0]->set_executed if $arap->id == $seis->[0]->arap_id;
- }
- }
- }
-
- flash('ok', t8('#1 proposal(s) saved.', scalar @{ $::form->{proposal_ids} }));
-
- $self->action_list();
-}
-
#
# filters
#
diff --git a/SL/Controller/CsvImport/BankTransaction.pm b/SL/Controller/CsvImport/BankTransaction.pm
index 5397d27d9..d6a7e87aa 100644
--- a/SL/Controller/CsvImport/BankTransaction.pm
+++ b/SL/Controller/CsvImport/BankTransaction.pm
@@ -83,26 +83,29 @@ sub check_existing {
};
}
+sub _displayable_columns {
+ (
+ { name => 'local_bank_code', description => $::locale->text('Own bank code') },
+ { name => 'local_account_number', description => $::locale->text('Own bank account number or IBAN') },
+ { name => 'local_bank_account_id', description => $::locale->text('ID of own bank account') },
+ { name => 'remote_bank_code', description => $::locale->text('Bank code of the goal/source') },
+ { name => 'remote_account_number', description => $::locale->text('Account number of the goal/source') },
+ { name => 'transdate', description => $::locale->text('Date of transaction') },
+ { name => 'valutadate', description => $::locale->text('Valuta date') },
+ { name => 'amount', description => $::locale->text('Amount') },
+ { name => 'currency', description => $::locale->text('Currency') },
+ { name => 'currency_id', description => $::locale->text('Currency (database ID)') },
+ { name => 'remote_name', description => $::locale->text('Name of the goal/source (if field names remote_name and remote_name_1 exist they will be combined into field "remote_name")') },
+ { name => 'purpose', description => $::locale->text('Purpose (if field names purpose, purpose1, purpose2 ... exist they will all combined into the field "purpose")') }
+ );
+}
+
sub setup_displayable_columns {
my ($self) = @_;
$self->SUPER::setup_displayable_columns;
- $self->add_displayable_columns({ name => 'local_bank_code', description => $::locale->text('Own bank code') },
- { name => 'local_account_number', description => $::locale->text('Own bank account number or IBAN') },
- { name => 'local_bank_account_id', description => $::locale->text('ID of own bank account') },
- { name => 'remote_bank_code', description => $::locale->text('Bank code of the goal/source') },
- { name => 'remote_account_number', description => $::locale->text('Account number of the goal/source') },
- { name => 'transdate', description => $::locale->text('Date of transaction') },
- { name => 'valutadate', description => $::locale->text('Valuta date') },
- { name => 'amount', description => $::locale->text('Amount') },
- { name => 'currency', description => $::locale->text('Currency') },
- { name => 'currency_id', description => $::locale->text('Currency (database ID)') },
- { name => 'remote_name', description => $::locale->text('Name of the goal/source (if field names remote_name and remote_name_1 exist they will be combined into field "remote_name")') },
- { name => 'purpose', description => $::locale->text('Purpose (if field names purpose, purpose1, purpose2 ... exist they will all combined into the field "purpose")') },
- { name => 'transactionCode', description => $::locale->text('Transaction Code') },
- { name => 'transactionText', description => $::locale->text('Transaction Text') },
- );
+ $self->add_displayable_columns($self->_displayable_columns);
}
sub check_bank_account {
diff --git a/SL/DB/BankTransaction.pm b/SL/DB/BankTransaction.pm
index 053abb410..e91651a98 100644
--- a/SL/DB/BankTransaction.pm
+++ b/SL/DB/BankTransaction.pm
@@ -112,6 +112,7 @@ sub get_agreement_with_invoice {
if ( $invoice->skonto_date && abs(abs($invoice->amount_less_skonto) - abs($self->amount)) < 0.01) {
$agreement += $points{skonto_exact_amount};
$rule_matches .= 'skonto_exact_amount(' . $points{'skonto_exact_amount'} . ') ';
+ $invoice->{skonto_type} = 'with_skonto_pt';
};
#search invoice number in purpose
@@ -208,27 +209,27 @@ sub get_agreement_with_invoice {
};
};
- # if there is exactly one non-executed sepa_export_item for the invoice
- if ( my $seis = $invoice->find_sepa_export_items({ executed => 0 }) ) {
- if ( scalar @$seis == 1 ) {
- my $sei = $seis->[0];
-
- # test for amount and id matching only, sepa transfer date and bank
- # transaction date needn't match
- my $arap = $invoice->is_sales ? 'ar' : 'ap';
- if ( abs($self->amount) == ($sei->amount)
- && $invoice->id == $sei->arap_id
- ) {
- $agreement += $points{sepa_export_item};
- $rule_matches .= 'sepa_export_item(' . $points{'sepa_export_item'} . ') ';
- };
- } else {
- # zero or more than one sepa_export_item, do nothing for this invoice
- # zero: do nothing, no sepa_export_item exists, no match
- # more than one: does this ever apply? Currently you can't create sepa
- # exports for invoices that already have a non-executed sepa_export
- };
- };
+# # if there is exactly one non-executed sepa_export_item for the invoice
+# if ( my $seis = $invoice->find_sepa_export_items({ executed => 0 }) ) {
+# if ( scalar @$seis == 1 ) {
+# my $sei = $seis->[0];
+#
+# # test for amount and id matching only, sepa transfer date and bank
+# # transaction date needn't match
+# my $arap = $invoice->is_sales ? 'ar' : 'ap';
+# if ( abs($self->amount) == ($sei->amount)
+# && $invoice->id == $sei->arap_id
+# ) {
+# $agreement += $points{sepa_export_item};
+# $rule_matches .= 'sepa_export_item(' . $points{'sepa_export_item'} . ') ';
+# };
+# } else {
+# # zero or more than one sepa_export_item, do nothing for this invoice
+# # zero: do nothing, no sepa_export_item exists, no match
+# # more than one: does this ever apply? Currently you can't create sepa
+# # exports for invoices that already have a non-executed sepa_export
+# };
+# };
return ($agreement,$rule_matches);
};
diff --git a/SL/DB/Helper/Payment.pm b/SL/DB/Helper/Payment.pm
index 2507e45ec..9ff921617 100644
--- a/SL/DB/Helper/Payment.pm
+++ b/SL/DB/Helper/Payment.pm
@@ -94,7 +94,7 @@ sub pay_invoice {
if ( $params{'payment_type'} eq 'difference_as_skonto' ) {
croak "amount $params{amount} doesn't match open amount " . $self->open_amount . ", diff = " . ($params{amount}-$self->open_amount) if $params{amount} && abs($self->open_amount - $params{amount} ) > 0.0000001;
} elsif ( $params{'payment_type'} eq 'with_skonto_pt' ) {
- croak "amount $params{amount} doesn't match amount less skonto: " . $self->open_amount . "\n" if $params{amount} && abs($self->amount_less_skonto - $params{amount} ) > 0.0000001;
+ croak "amount $params{amount} doesn't match amount less skonto: " . $self->amount_less_skonto . "\n" if $params{amount} && abs($self->amount_less_skonto - $params{amount} ) > 0.0000001;
croak "payment type with_skonto_pt can't be used if payments have already been made" if $self->paid != 0;
};
@@ -635,11 +635,12 @@ sub get_payment_select_options_for_bank_transaction {
die unless $bt;
my $open_amount = $self->open_amount;
-
+ #$main::lxdebug->message(LXDebug->DEBUG2(),"skonto_date=".$self->skonto_date." open amount=".$open_amount);
my @options;
if ( $open_amount && # invoice amount not 0
$self->skonto_date && # check whether skonto applies
- abs(abs($self->amount_less_skonto) - abs($bt->amount)) < 0.01 &&
+ ( abs(abs($self->amount_less_skonto) - abs($bt->amount)) < 0.01 ||
+ ( $bt->transactioncode eq "191" && abs($self->amount_less_skonto) < abs($bt->amount) )) &&
$self->check_skonto_configuration) {
if ( $self->within_skonto_period($bt->transdate) ) {
push(@options, { payment_type => 'without_skonto', display => t8('without skonto') });
diff --git a/SL/SEPA.pm b/SL/SEPA.pm
index b8cdee03f..a9ba2f3da 100644
--- a/SL/SEPA.pm
+++ b/SL/SEPA.pm
@@ -46,7 +46,9 @@ sub retrieve_open_invoices {
COALESCE(vc.iban, '') <> '' AND COALESCE(vc.bic, '') <> '' ${mandate} AS vc_bank_info_ok,
- ${arap}.amount - ${arap}.paid - COALESCE(open_transfers.amount, 0) AS open_amount
+ ${arap}.amount - ${arap}.paid - COALESCE(open_transfers.amount, 0) AS open_amount,
+ COALESCE(open_transfers.amount, 0) AS transfer_amount,
+ pt.description as pt_description
FROM ${arap}
LEFT JOIN ${vc} vc ON (${arap}.${vc}_id = vc.id)
@@ -64,6 +66,7 @@ sub retrieve_open_invoices {
ORDER BY lower(vc.name) ASC, lower(${arap}.invnumber) ASC
|;
+ # $main::lxdebug->message(LXDebug->DEBUG2(),"sepa add query:".$query);
my $results = selectall_hashref_query($form, $dbh, $query);
diff --git a/locale/de/all b/locale/de/all
index d9ad39728..56478f53a 100755
--- a/locale/de/all
+++ b/locale/de/all
@@ -20,9 +20,11 @@ $self->{texts} = {
'#1 additional part(s)' => '#1 zusätzliche(r) Artikel',
'#1 dunnings have been deleted' => '#1 Mahnung(en) wurden gelöscht',
'#1 h' => '#1 h',
+ '#1 invoice(s) saved.' => '#1 Rechnung(en) abgespeichert.',
'#1 of #2 importable objects were imported.' => '#1 von #2 importierbaren Objekten wurden importiert.',
'#1 prices were updated.' => '#1 Preise wurden aktualisiert.',
'#1 proposal(s) saved.' => '#1 Vorschläge gespeichert.',
+ '#1 proposal(s) with #2 invoice(s) saved.' => '#1 Vorschlag(e) mit #2 Rechnung(en) abgespeichert',
'#1 section(s)' => '#1 Abschnitt(e)',
'#1 text block(s) back' => '#1 Textlock/-blöcke vorne',
'#1 text block(s) front' => '#1 Textblock/-blöcke hinten',
diff --git a/templates/webpages/bank_transactions/list.html b/templates/webpages/bank_transactions/list.html
index c810c8f9c..54351a91d 100644
--- a/templates/webpages/bank_transactions/list.html
+++ b/templates/webpages/bank_transactions/list.html
@@ -14,26 +14,16 @@
[% IF FORM.filter.todate %] [% 'to (date)' | $T8 %] [% FORM.filter.todate %][% END %]
-