+ } 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,
+ sources => [ map { $::form->{"sources_${bank_transaction_id}_${_}"} } @{ $invoice_ids } ],
+ memos => [ map { $::form->{"memos_${bank_transaction_id}_${_}"} } @{ $invoice_ids } ],
+ );
+ $count += scalar( @{$invoice_ids} );
+ }
+ }
+ my $max_count = $count;
+ foreach (@{ $self->problems }) {
+ $count-- if $_->{result} eq 'error';
+ }
+ return ($count, $max_count);
+}
+
+sub action_save_invoices {
+ my ($self) = @_;
+ my ($success_count, $max_count) = $self->save_invoices();
+
+ if ($success_count == $max_count) {
+ flash('ok', t8('#1 invoice(s) saved.', $success_count));
+ } else {
+ flash('error', t8('At least #1 invoice(s) not saved', $max_count - $success_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 save_single_bank_transaction {
+ my ($self, %params) = @_;
+
+ my %data = (
+ %params,
+ bank_transaction => SL::DB::Manager::BankTransaction->find_by(id => $params{bank_transaction_id}),
+ invoices => [],
+ );
+
+ if (!$data{bank_transaction}) {
+ return {
+ %data,
+ result => 'error',
+ message => $::locale->text('The ID #1 is not a valid database ID.', $data{bank_transaction_id}),
+ };
+ }
+
+ my $bank_transaction = $data{bank_transaction};
+
+ if ($bank_transaction->closed_period) {
+ return {
+ %data,
+ result => 'error',
+ message => $::locale->text('Cannot post payment for a closed period!'),
+ };
+ }
+ my (@warnings);
+
+ my $worker = sub {
+ my $bt_id = $data{bank_transaction_id};
+ my $sign = $bank_transaction->amount < 0 ? -1 : 1;
+ my $payment_received = $bank_transaction->amount > 0;
+ my $payment_sent = $bank_transaction->amount < 0;
+
+
+ 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) {
+ return {
+ %data,
+ result => 'error',
+ message => $::locale->text("The ID #1 is not a valid database ID.", $invoice_id),
+ };
+ }
+ push @{ $data{invoices} }, $invoice;
+ }
+
+ 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."),
+ };
+ }
+
+ if ( $payment_sent
+ && any { ( $_->is_sales && ($_->amount > 0))
+ || (!$_->is_sales && ($_->amount < 0) && ($_->invoice_type eq 'purchase_invoice'))
+ } @{ $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(@{ $data{invoices} });