Eine Bankbuchung darf zwar mehrere Rechnungen begleichen, aber jede
Rechnung nur einmal. Daher wird vor dem verbuchen geprüft, ob es für die
Bankbuchung schon eine Verknüpfung zu der Rechnung gibt.
my $invoice_hash = delete $::form->{invoice_ids}; # each key (the bt line with a bt_id) contains an array of invoice_ids
my $skonto_hash = delete $::form->{invoice_skontos} || {}; # array containing the payment type, could be empty
my $invoice_hash = delete $::form->{invoice_ids}; # each key (the bt line with a bt_id) contains an array of invoice_ids
my $skonto_hash = delete $::form->{invoice_skontos} || {}; # array containing the payment type, could be empty
+ # a bank_transaction may be assigned to several invoices, i.e. a customer
+ # might pay several open invoices with one transaction
+
while ( my ($bt_id, $invoice_ids) = each(%$invoice_hash) ) {
my $bank_transaction = SL::DB::Manager::BankTransaction->find_by(id => $bt_id);
my $sign = $bank_transaction->amount < 0 ? -1 : 1;
while ( my ($bt_id, $invoice_ids) = each(%$invoice_hash) ) {
my $bank_transaction = SL::DB::Manager::BankTransaction->find_by(id => $bt_id);
my $sign = $bank_transaction->amount < 0 ? -1 : 1;
return 1; } @invoices if $bank_transaction->amount < 0;
foreach my $invoice (@invoices) {
return 1; } @invoices if $bank_transaction->amount < 0;
foreach my $invoice (@invoices) {
+
+ # Check if bank_transaction already has a link to the invoice, may only be linked once per invoice
+ # This might be caused by the user reloading a page and resending the form
+ die t8("Bank transaction with id #1 has already been linked to #2.", $bank_transaction->id, $invoice->displayable_name)
+ if _existing_record_link($bank_transaction, $invoice);
+
my $payment_type;
if ( defined $skonto_hash->{"$bt_id"} ) {
$payment_type = shift(@{ $skonto_hash->{"$bt_id"} });
my $payment_type;
if ( defined $skonto_hash->{"$bt_id"} ) {
$payment_type = shift(@{ $skonto_hash->{"$bt_id"} });
$bank_transaction->remote_bank_code));
last;
}
$bank_transaction->remote_bank_code));
last;
}
- #pay invoice or go to the next bank transaction if the amount is not sufficiently high
+ # pay invoice or go to the next bank transaction if the amount is not sufficiently high
if ($invoice->amount <= $amount_of_transaction) {
$invoice->pay_invoice(chart_id => $bank_transaction->local_bank_account->chart_id,
trans_id => $invoice->id,
if ($invoice->amount <= $amount_of_transaction) {
$invoice->pay_invoice(chart_id => $bank_transaction->local_bank_account->chart_id,
trans_id => $invoice->id,
$amount_of_transaction = 0;
}
$amount_of_transaction = 0;
}
- #Record a link from the bank transaction to the invoice
+ # Record a record link from the bank transaction to the invoice
my @props = (
from_table => 'bank_transactions',
from_id => $bt_id,
my @props = (
from_table => 'bank_transactions',
from_id => $bt_id,
to_id => $invoice->id,
);
to_id => $invoice->id,
);
- my $existing = SL::DB::Manager::RecordLink->get_all(where => \@props, limit => 1)->[0];
-
- SL::DB::RecordLink->new(@props)->save if !$existing;
+ SL::DB::RecordLink->new(@props)->save;
}
$bank_transaction->save;
}
}
$bank_transaction->save;
}
my ($self) = @_;
foreach my $bt_id (@{ $::form->{proposal_ids} }) {
my ($self) = @_;
foreach my $bt_id (@{ $::form->{proposal_ids} }) {
my $bt = SL::DB::Manager::BankTransaction->find_by(id => $bt_id);
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
$bt->invoice_amount($bt->amount);
$bt->save;
#pay invoice
- 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;
$arap->pay_invoice(chart_id => $bt->local_bank_account->chart_id,
trans_id => $arap->id,
amount => $arap->amount,
$arap->pay_invoice(chart_id => $bt->local_bank_account->chart_id,
trans_id => $arap->id,
amount => $arap->amount,
- my $existing = SL::DB::Manager::RecordLink->get_all(where => \@props, limit => 1)->[0];
-
- SL::DB::RecordLink->new(@props)->save if !$existing;
+ SL::DB::RecordLink->new(@props)->save;
}
flash('ok', t8('#1 proposal(s) saved.', scalar @{ $::form->{proposal_ids} }));
}
flash('ok', t8('#1 proposal(s) saved.', scalar @{ $::form->{proposal_ids} }));
+sub _existing_record_link {
+ my ($bt, $invoice) = @_;
+
+ # check whether a record link from banktransaction $bt already exists to
+ # invoice $invoice, returns 1 if that is the case
+
+ die unless $bt->isa("SL::DB::BankTransaction") && ( $invoice->isa("SL::DB::Invoice") || $invoice->isa("SL::DB::PurchaseInvoice") );
+
+ my $linked_record_to_table = $invoice->is_sales ? 'Invoice' : 'PurchaseInvoice';
+ my $linked_records = $bt->linked_records( direction => 'to', to => $linked_record_to_table, query => [ id => $invoice->id ] );
+
+ return @$linked_records ? 1 : 0;
+};
+
+
sub init_models {
my ($self) = @_;
sub init_models {
my ($self) = @_;
'Bank collection via SEPA' => 'Bankeinzug via SEPA',
'Bank collections via SEPA' => 'Bankeinzüge via SEPA',
'Bank transaction' => 'Bankbuchung',
'Bank collection via SEPA' => 'Bankeinzug via SEPA',
'Bank collections via SEPA' => 'Bankeinzüge via SEPA',
'Bank transaction' => 'Bankbuchung',
+ 'Bank transaction with id #1 has already been linked to #2.' => 'Bankbuchung mit id #1 wurde schon mit #2 verlinkt.',
'Bank transactions' => 'Bankbewegungen',
'Bank transactions MT940' => 'Kontoauszug verbuchen',
'Bank transfer amount' => 'Überweisungssumme',
'Bank transactions' => 'Bankbewegungen',
'Bank transactions MT940' => 'Kontoauszug verbuchen',
'Bank transfer amount' => 'Überweisungssumme',