X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FCsvImport.pm;h=23f333263c0502e8cdd5048c1e9dbc01101b9aef;hb=d14f72e7f3ce339b7565e27fcb169181ff90d64b;hp=4db025e7d3f056f84a027f020044dd584d15af32;hpb=d74921657d967900bded4aaf4805647e9cf83562;p=kivitendo-erp.git diff --git a/SL/Controller/CsvImport.pm b/SL/Controller/CsvImport.pm index 4db025e7d..23f333263 100644 --- a/SL/Controller/CsvImport.pm +++ b/SL/Controller/CsvImport.pm @@ -6,6 +6,7 @@ use SL::DB::Buchungsgruppe; use SL::DB::CsvImportProfile; use SL::DB::CsvImportReport; use SL::DB::Unit; +use SL::DB::Helper::Paginated (); use SL::Helper::Flash; use SL::SessionFile; use SL::Controller::CsvImport::Contact; @@ -17,6 +18,7 @@ use SL::BackgroundJob::CsvImport; use SL::System::TaskServer; use List::MoreUtils qw(none); +use List::Util qw(min); use parent qw(SL::Controller::Base); @@ -36,6 +38,8 @@ __PACKAGE__->run_before('ensure_form_structure'); __PACKAGE__->run_before('check_type', except => [ qw(report) ]); __PACKAGE__->run_before('load_all_profiles'); +__PACKAGE__->run_after('cleanup_reports'); + # # actions # @@ -89,10 +93,14 @@ sub action_result { $self->profile($profile); - if ($data->{progress} < 100) { - $self->render('csv_import/_deferred_results', { no_layout => 1 }); + if ($data->{errors} and my $first_error = $data->{errors}->[0]) { + flash('error', $::locale->text('There was an error parsing the csv file: #1 in line #2.', $first_error->[2], $first_error->[0])); + } + + if ($data->{progress}{finished} || $data->{errors}) { + $self->render('csv_import/_deferred_report', { no_layout => 1 }); } else { - $self->action_report(report_id => $data->{report_id}, no_layout => 1); + $self->render('csv_import/_deferred_results', { no_layout => 1 }); } } @@ -119,9 +127,49 @@ sub action_download_sample { sub action_report { my ($self, %params) = @_; - $self->{report} = SL::DB::Manager::CsvImportReport->find_by(id => $params{report_id} || $::form->{id}); + my $report_id = $params{report_id} || $::form->{id}; + + $self->{report} = SL::DB::Manager::CsvImportReport->find_by(id => $report_id); + my $num_rows = SL::DB::Manager::CsvImportReportRow->get_all_count(query => [ csv_import_report_id => $report_id ]); + my $num_cols = SL::DB::Manager::CsvImportReportRow->get_all_count(query => [ csv_import_report_id => $report_id, row => 0 ]); + + # manual paginating, yuck + my $page = $::form->{page} || 1; + my $pages = {}; + $pages->{per_page} = $::form->{per_page} || 20; + $pages->{max} = SL::DB::Helper::Paginated::ceil($num_rows / ($num_cols || 1), $pages->{per_page}) || 1; + $pages->{cur} = $page < 1 ? 1 + : $page > $pages->{max} ? $pages->{max} + : $page; + $pages->{common} = SL::DB::Helper::Paginated::make_common_pages($pages->{cur}, $pages->{max}); + + $self->{display_rows} = [ + 0, + $pages->{per_page} * ($pages->{cur}-1) + 1 + .. + min($pages->{per_page} * $pages->{cur}, $num_rows / ($num_cols || 1) - 1) + ]; + + my @query = ( + csv_import_report_id => $report_id, + or => [ + row => 0, + and => [ + row => { gt => $pages->{per_page} * ($pages->{cur}-1) }, + row => { le => $pages->{per_page} * $pages->{cur} }, + ] + ] + ); + + my $rows = SL::DB::Manager::CsvImportReportRow->get_all(query => \@query); + my $status = SL::DB::Manager::CsvImportReportStatus->get_all(query => \@query); + + $self->{report_rows} = $self->{report}->folded_rows(rows => $rows); + $self->{report_status} = $self->{report}->folded_status(status => $status); + $self->{pages} = $pages; + $self->{base_url} = $self->url_for(action => 'report', id => $report_id, no_layout => $params{no_layout} || $::form->{no_layout} ); - $self->render('csv_import/report', { no_layout => $params{no_layout} }); + $self->render('csv_import/report', { no_layout => $params{no_layout} || $::form->{no_layout} }); } @@ -202,10 +250,17 @@ sub test_and_import_deferred { $file->fh->close; } + my $file = SL::SessionFile->new($self->csv_file_name, mode => '<', encoding => $self->profile->get('charset')); + if (!$file->fh) { + flash('error', $::locale->text('No file has been uploaded yet.')); + return $self->action_new; + } + $self->{background_job} = SL::BackgroundJob::CsvImport->create_job( file => $self->csv_file_name, profile => $self->profile, type => $self->profile->type, + test => $params{test}, )->save; SL::System::TaskServer->start_if_not_running; @@ -234,6 +289,8 @@ sub test_and_import { $worker->run; + return if $self->errors; + $self->num_imported(0); $worker->save_objects if !$params{test}; @@ -313,6 +370,8 @@ sub char_map { sub save_report { my ($self, $report_id) = @_; + $self->track_progress(phase => 'building report', progress => 0); + my $clone_profile = $self->profile->clone_and_reset_deep; $clone_profile->save; # weird bug. if this isn't saved before adding it to the report, it will default back to the last profile. @@ -333,14 +392,23 @@ sub save_report { my $sth2 = $dbh->prepare($query2); # save headers - my @headers = ( - grep({ $self->info_headers->{used}->{$_} } @{ $self->info_headers->{headers} }), - grep({ $self->headers->{used}->{$_} } @{ $self->headers->{headers} }), - grep({ $self->raw_data_headers->{used}->{$_} } @{ $self->raw_data_headers->{headers} }), - ); - my @info_methods = grep { $self->info_headers->{used}->{$_} } @{ $self->info_headers->{headers} }; - my @methods = grep { $self->headers->{used}->{$_} } @{ $self->headers->{methods} }; - my @raw_methods = grep { $self->raw_data_headers->{used}->{$_} } @{ $self->raw_data_headers->{headers} }; + my (@headers, @info_methods, @raw_methods, @methods); + + for my $i (0 .. $#{ $self->info_headers->{headers} }) { + next unless $self->info_headers->{used}->{ $self->info_headers->{headers}->[$i] }; + push @headers, $self->info_headers->{headers}->[$i]; + push @info_methods, $self->info_headers->{methods}->[$i]; + } + for my $i (0 .. $#{ $self->headers->{headers} }) { + next unless $self->headers->{used}->{ $self->headers->{headers}->[$i] }; + push @headers, $self->headers->{headers}->[$i]; + push @methods, $self->headers->{methods}->[$i]; + } + for my $i (0 .. $#{ $self->raw_data_headers->{headers} }) { + next unless $self->raw_data_headers->{used}->{ $self->raw_data_headers->{headers}->[$i] }; + push @headers, $self->raw_data_headers->{headers}->[$i]; + push @raw_methods, $self->raw_data_headers->{headers}->[$i]; + } $sth->execute($report->id, $_, 0, $headers[$_]) for 0 .. $#headers; @@ -349,6 +417,7 @@ sub save_report { my $o2 = $o1 + @methods; for my $row (0 .. $#{ $self->data }) { + $self->track_progress(progress => $row / @{ $self->data } * 100) if $row % 100 == 0; my $data_row = $self->{data}[$row]; $sth->execute($report->id, $_, $row + 1, $data_row->{info_data}{ $info_methods[$_] }) for 0 .. $#info_methods; @@ -393,12 +462,16 @@ sub setup_help { } sub track_progress { - my ($self, $progress) = @_; + my ($self, %params) = @_; for my $tracker ($self->progress_tracker) { - $tracker->track_progress($progress); + $tracker->track_progress(%params); } } +sub cleanup_reports { + SL::DB::Manager::CsvImportReport->cleanup; +} + 1;