X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FBankTransaction.pm;h=e38f8a9972d1787bed42db8cb08793401ce8d0de;hb=23d55c8535d9eecc415791d42ec05a7d9cb5c8e0;hp=86ff35eba44d6120768c011ca044b996a2bfb95f;hpb=c210bdb53bc5ba45aeb46999d1e024ca09812e5c;p=kivitendo-erp.git diff --git a/SL/Controller/BankTransaction.pm b/SL/Controller/BankTransaction.pm index 86ff35eba..e38f8a997 100644 --- a/SL/Controller/BankTransaction.pm +++ b/SL/Controller/BankTransaction.pm @@ -68,32 +68,21 @@ sub action_list_all { $self->report_generator_list_objects(report => $self->{report}, objects => $self->models->get); } -sub action_list { - my ($self) = @_; - - if (!$::form->{filter}{bank_account}) { - flash('error', t8('No bank account chosen!')); - $self->action_search; - return; - } +sub gather_bank_transactions_and_proposals { + my ($self, %params) = @_; - my $sort_by = $::form->{sort_by} || 'transdate'; + my $sort_by = $params{sort_by} || 'transdate'; $sort_by = 'transdate' if $sort_by eq 'proposal'; - $sort_by .= $::form->{sort_dir} ? ' DESC' : ' ASC'; - - my $fromdate = $::locale->parse_date_to_object($::form->{filter}->{fromdate}); - my $todate = $::locale->parse_date_to_object($::form->{filter}->{todate}); - $todate->add( days => 1 ) if $todate; + $sort_by .= $params{sort_dir} ? ' DESC' : ' ASC'; my @where = (); - push @where, (transdate => { ge => $fromdate }) if ($fromdate); - push @where, (transdate => { lt => $todate }) if ($todate); - my $bank_account = SL::DB::Manager::BankAccount->find_by( id => $::form->{filter}{bank_account} ); + push @where, (transdate => { ge => $params{fromdate} }) if $params{fromdate}; + push @where, (transdate => { lt => $params{todate} }) if $params{todate}; # bank_transactions no younger than starting date, # including starting date (same search behaviour as fromdate) # but OPEN invoices to be matched may be from before - if ( $bank_account->reconciliation_starting_date ) { - push @where, (transdate => { ge => $bank_account->reconciliation_starting_date }); + if ( $params{bank_account}->reconciliation_starting_date ) { + push @where, (transdate => { ge => $params{bank_account}->reconciliation_starting_date }); }; my $bank_transactions = SL::DB::Manager::BankTransaction->get_all( @@ -101,24 +90,28 @@ sub action_list { sort_by => $sort_by, limit => 10000, where => [ - amount => {ne => \'invoice_amount'}, - local_bank_account_id => $::form->{filter}{bank_account}, + amount => {ne => \'invoice_amount'}, # '} make emacs happy + local_bank_account_id => $params{bank_account}->id, cleared => 0, @where ], ); # credit notes have a negative amount, treat differently - my $all_open_ar_invoices = SL::DB::Manager::Invoice ->get_all(where => [ or => [ amount => { gt => \'paid' }, - and => [ type => 'credit_note', - amount => { lt => \'paid' } - ], - ], - ], - with_objects => ['customer','payment_terms']); - - my $all_open_ap_invoices = SL::DB::Manager::PurchaseInvoice->get_all(where => [amount => { ne => \'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']); + my $all_open_ar_invoices = SL::DB::Manager::Invoice->get_all(where => [ or => [ amount => { gt => \'paid' }, # '} make emacs happy + and => [ type => 'credit_note', + amount => { lt => \'paid' } # '} make emacs happy + ], + ], + ], + with_objects => ['customer','payment_terms']); + + my $all_open_ap_invoices = SL::DB::Manager::PurchaseInvoice->get_all(where => [amount => { ne => \'paid' }], # '}] make emacs happy + with_objects => ['vendor' ,'payment_terms']); + my $all_open_sepa_export_items = SL::DB::Manager::SepaExportItem->get_all(where => [chart_id => $params{bank_account}->chart_id , + 'sepa_export.executed' => 0, + 'sepa_export.closed' => 0 + ], + with_objects => ['sepa_export']); my @all_open_invoices; # filter out invoices with less than 1 cent outstanding @@ -174,8 +167,6 @@ sub action_list { } next if $found; # batch transaction has no remotename !! - } else { - next unless $bt->{remote_name}; # bank has no name, usually fees, use create invoice to assign } # try to match the current $bt to each of the open_invoices, saving the @@ -217,38 +208,52 @@ sub action_list { # to qualify as a proposal there has to be # * agreement >= 5 TODO: make threshold configurable in configuration # * 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 @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 - if ($::form->{sort_by} && $::form->{sort_by} eq 'proposal') { - if ($::form->{sort_dir}) { - $bank_transactions = [ sort { $a->{agreement} <=> $b->{agreement} } @{ $bank_transactions } ]; - } else { - $bank_transactions = [ sort { $b->{agreement} <=> $a->{agreement} } @{ $bank_transactions } ]; - } + if ($params{sort_by} && $params{sort_by} eq 'proposal') { + my $dir = $params{sort_dir} ? 1 : -1; + $bank_transactions = [ sort { ($a->{agreement} <=> $b->{agreement}) * $dir } @{ $bank_transactions } ]; } - # for testing with t/bank/banktransaction.t : - if ( $::form->{dont_render_for_test} ) { - return ( $bank_transactions , \@proposals ); + return ( $bank_transactions , \@proposals ); +} + +sub action_list { + my ($self) = @_; + + if (!$::form->{filter}{bank_account}) { + flash('error', t8('No bank account chosen!')); + $self->action_search; + return; } + my $bank_account = SL::DB::BankAccount->load_cached($::form->{filter}->{bank_account}); + my $fromdate = $::locale->parse_date_to_object($::form->{filter}->{fromdate}); + my $todate = $::locale->parse_date_to_object($::form->{filter}->{todate}); + $todate->add( days => 1 ) if $todate; + + my ($bank_transactions, $proposals) = $self->gather_bank_transactions_and_proposals( + bank_account => $bank_account, + fromdate => $fromdate, + todate => $todate, + sort_by => $::form->{sort_by}, + sort_dir => $::form->{sort_dir}, + ); + $::request->layout->add_javascripts("kivi.BankTransaction.js"); $self->render('bank_transactions/list', title => t8('Bank transactions MT940'), BANK_TRANSACTIONS => $bank_transactions, - PROPOSALS => \@proposals, + PROPOSALS => $proposals, bank_account => $bank_account, - ui_tab => scalar(@proposals) > 0?1:0, + ui_tab => scalar(@{ $proposals }) > 0 ? 1 : 0, ); } @@ -273,12 +278,14 @@ sub action_create_invoice { my $templates_ap = SL::DB::Manager::RecordTemplate->get_all( where => [ template_type => 'ap_transaction' ], + sort_by => [ qw(template_name) ], with_objects => [ qw(employee vendor) ], ); my $templates_gl = SL::DB::Manager::RecordTemplate->get_all( query => [ template_type => 'gl_transaction', chart_id => SL::DB::Manager::BankAccount->find_by(id => $self->transaction->local_bank_account_id)->chart_id, ], + sort_by => [ qw(template_name) ], with_objects => [ qw(employee record_template_items) ], ); @@ -292,14 +299,21 @@ sub action_create_invoice { 'filter.fromdate' => $::form->{filter}->{fromdate}, )); - $self->render( - 'bank_transactions/create_invoice', - { layout => 0 }, - title => t8('Create invoice'), - TEMPLATES_GL => $use_vendor_filter && @{ $templates_ap } ? undef : $templates_gl, - TEMPLATES_AP => $templates_ap, - vendor_name => $use_vendor_filter && @{ $templates_ap } ? $vendor_of_transaction->name : undef, - ); + # if we have exactly one ap match, use this directly + if (1 == scalar @{ $templates_ap }) { + $self->redirect_to($self->load_ap_record_template_url($templates_ap->[0])); + + } else { + my $dialog_html = $self->render( + 'bank_transactions/create_invoice', + { layout => 0, output => 0 }, + title => t8('Create invoice'), + TEMPLATES_GL => $use_vendor_filter && @{ $templates_ap } ? undef : $templates_gl, + TEMPLATES_AP => $templates_ap, + vendor_name => $use_vendor_filter && @{ $templates_ap } ? $vendor_of_transaction->name : undef, + ); + $self->js->run('kivi.BankTransaction.show_create_invoice_dialog', $dialog_html)->render; + } } sub action_ajax_payment_suggestion { @@ -677,6 +691,7 @@ sub save_single_bank_transaction { source => $source, memo => $memo, skonto_amount => $free_skonto_amount, + bt_id => $bt_id, transdate => $bank_transaction->valutadate->to_kivitendo); # ... and record the origin via BankTransactionAccTrans if (scalar(@acc_ids) < 2) { @@ -791,9 +806,10 @@ sub action_unlink_bank_transaction { my $query = qq|UPDATE $type SET paid = (SELECT COALESCE(abs(sum(amount)),0) FROM acc_trans WHERE trans_id = ? - AND chart_link ilike '%paid%')|; + AND chart_link ilike '%paid%') + WHERE id = ?|; - die if (do_query($::form, $bank_transaction->db->dbh, $query, $trans_id) == -1); + die if (do_query($::form, $bank_transaction->db->dbh, $query, $trans_id, $trans_id) == -1); } # 4. and delete all (if any) record links my $rl = SL::DB::Manager::RecordLink->delete_all(where => [ from_id => $bt_id, from_table => 'bank_transactions' ]); @@ -802,6 +818,14 @@ sub action_unlink_bank_transaction { $bank_transaction->invoice_amount(0); $bank_transaction->cleared(0); $bank_transaction->save; + # 6. and add a log entry in history_erp + SL::DB::History->new( + trans_id => $bank_transaction->id, + snumbers => 'bank_transaction_unlink_' . $bank_transaction->id, + employee_id => SL::DB::Manager::Employee->current->id, + what_done => 'bank_transaction', + addition => 'UNLINKED', + )->save(); 1; @@ -838,6 +862,7 @@ sub make_filter_summary { [ $filter->{"valutadate:date::le"}, $::locale->text('Valutadate') . " " . $::locale->text('To Date') ], [ $filter->{"amount:number"}, $::locale->text('Amount') ], [ $filter->{"bank_account_id:integer"}, $::locale->text('Local bank account') ], + [ $filter->{"remote_name:substr::ilike"}, $::locale->text('Remote name') ], ); for (@filters) {