use SL::DB::BankAccount;
use SL::DBUtils qw(like);
use SL::Presenter;
+
+use List::MoreUtils qw(any);
use List::Util qw(max);
use Rose::Object::MakeMethods::Generic
my $bank_transaction = $data{bank_transaction};
my $sign = $bank_transaction->amount < 0 ? -1 : 1;
my $amount_of_transaction = $sign * $bank_transaction->amount;
+ my $payment_received = $bank_transaction->amount > 0;
+ my $payment_sent = $bank_transaction->amount < 0;
- my @invoices;
foreach my $invoice_id (@{ $params{invoice_ids} }) {
my $invoice = SL::DB::Manager::Invoice->find_by(id => $invoice_id) || SL::DB::Manager::PurchaseInvoice->find_by(id => $invoice_id);
if (!$invoice) {
};
}
- push @invoices, $invoice;
+ push @{ $data{invoices} }, $invoice;
}
- $data{invoices} = \@invoices;
+ if ( $payment_received
+ && any { ( $_->is_sales && ($_->amount < 0))
+ || (!$_->is_sales && ($_->amount > 0))
+ } @{ $data{invoices} }) {
+ return {
+ %data,
+ result => 'error',
+ message => $::locale->text("Received payments can only be posted for sales invoices and purchase credit notes."),
+ };
+ }
- @invoices = sort { return 1 if ( $a->is_sales and $a->amount > 0);
- return 1 if (!$a->is_sales and $a->amount < 0);
- return -1;
- } @invoices if $bank_transaction->amount > 0;
- @invoices = sort { return -1 if ( $a->is_sales and $a->amount > 0);
- return -1 if (!$a->is_sales and $a->amount < 0);
- return 1;
- } @invoices if $bank_transaction->amount < 0;
+ if ( $payment_sent
+ && any { ( $_->is_sales && ($_->amount > 0))
+ || (!$_->is_sales && ($_->amount < 0))
+ } @{ $data{invoices} }) {
+ return {
+ %data,
+ result => 'error',
+ message => $::locale->text("Sent payments can only be posted for purchase invoices and sales credit notes."),
+ };
+ }
- my $max_invoices = scalar(@invoices);
+ my $max_invoices = scalar(@{ $data{invoices} });
my $n_invoices = 0;
- foreach my $invoice (@invoices) {
+ foreach my $invoice (@{ $data{invoices} }) {
$n_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
if (_existing_record_link($bank_transaction, $invoice)) {
};
}
- if ($amount_of_transaction == 0) {
- push @warnings, {
+ if (!$amount_of_transaction && $invoice->open_amount) {
+ return {
%data,
- result => 'warning',
- message => $::locale->text('There are invoices which could not be paid by bank transaction #1 (Account number: #2, bank code: #3)!',
- $bank_transaction->purpose, $bank_transaction->remote_account_number, $bank_transaction->remote_bank_code),
+ result => 'error',
+ message => $::locale->text("A payment can only be posted for multiple invoices if the amount to post is equal to or bigger than the sum of the open amounts of the affected invoices."),
};
- last;
}
my $payment_type;
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
+ my $overpaid_amount = $amount_of_transaction - $invoice->open_amount;
$invoice->pay_invoice(chart_id => $bank_transaction->local_bank_account->chart_id,
trans_id => $invoice->id,
amount => $amount_of_transaction,
transdate => $bank_transaction->transdate->to_kivitendo);
$bank_transaction->invoice_amount($bank_transaction->amount);
$amount_of_transaction = 0;
+
+ if ($overpaid_amount >= 0.01) {
+ push @warnings, {
+ %data,
+ result => 'warning',
+ message => $::locale->text('Invoice #1 was overpaid by #2.', $invoice->invnumber, $::form->format_amount(\%::myconfig, $overpaid_amount, 2)),
+ };
+ }
}
# Record a record link from the bank transaction to the invoice