+sub action_result {
+ my $self = shift;
+
+ # load resultobject
+ $self->{background_job} = SL::DB::Manager::BackgroundJob->find_by(id => $::form->{job});
+
+ my $data = $self->{background_job}->data_as_hash;
+
+ my $profile = SL::DB::Manager::CsvImportProfile->find_by(id => $data->{profile_id});
+ $self->profile($profile);
+
+ 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: #3', $first_error->[2], $first_error->[0], $first_error->[1]));
+ }
+
+ if ($data->{progress}{finished} || $data->{errors}) {
+ $self->render('csv_import/_deferred_report', { layout => 0 });
+ } else {
+ if (!$self->task_server->is_running) {
+ $self->task_server->start;
+ $self->{status_text} = t8('Task Server is not running, starting it now. If this does not change, please check your task server config');
+ } elsif (my $phase = $data->{progress}{phase}) {
+ $self->{status_text} = "$data->{progress}{plan}{$phase} / $data->{progress}{num_phases} " . t8($phase);
+ } else {
+ $self->{status_text} = t8('Import not started yet, please wait...');
+ }
+
+ $self->render('csv_import/_deferred_results', { layout => 0 });
+ }
+}
+
+sub action_download_sample {
+ my $self = shift;
+
+ $self->profile_from_form;
+ $self->setup_help;
+
+ my $file_name = 'csv_import_sample_' . $self->type . '.csv';
+ my $file = SL::SessionFile->new($file_name, mode => '>', encoding => $self->profile->get('charset'));
+ my $csv = Text::CSV_XS->new({ binary => 1, map { ( $_ => $self->profile->get($_) ) } qw(sep_char escape_char quote_char),});
+
+ if ($self->worker->is_multiplexed) {
+ foreach my $p (@{ $self->worker->profile }) {
+ $csv->print($file->fh, [ map { $_->{name} } @{ $self->displayable_columns->{$p->{row_ident}} } ]);
+ $file->fh->print("\r\n");
+ }
+ foreach my $p (@{ $self->worker->profile }) {
+ $csv->print($file->fh, [ map { $_->{description} } @{ $self->displayable_columns->{$p->{row_ident}} } ]);
+ $file->fh->print("\r\n");
+ }
+ } else {
+ $csv->print($file->fh, [ map { $_->{name} } @{ $self->displayable_columns } ]);
+ $file->fh->print("\r\n");
+ $csv->print($file->fh, [ map { $_->{description} } @{ $self->displayable_columns } ]);
+ $file->fh->print("\r\n");
+ }
+
+ $file->fh->close;
+
+ $self->send_file($file->file_name, name => $file_name);
+}
+
+sub action_report {
+ my ($self, %params) = @_;
+
+ my $report_id = $params{report_id} || $::form->{id};
+ $self->{report} = SL::DB::Manager::CsvImportReport->find_by(id => $report_id);
+
+ if (!$self->{report}) {
+ $::form->error(t8('No report with id #1', $report_id));
+ }
+
+ my $num_rows = $self->{report}->numrows;
+
+ # 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, $pages->{per_page}) || 1;
+ $pages->{page} = $page < 1 ? 1
+ : $page > $pages->{max} ? $pages->{max}
+ : $ page;
+ $pages->{common} = [ grep { $_->{visible} } @{ SL::DB::Helper::Paginated::make_common_pages($pages->{page}, $pages->{max}) } ];
+
+ $self->{report_numheaders} = $self->{report}->numheaders;
+ my $first_row_header = 0;
+ my $last_row_header = $self->{report_numheaders} - 1;
+ my $first_row_data = $pages->{per_page} * ($pages->{page}-1) + $self->{report_numheaders};
+ my $last_row_data = min($pages->{per_page} * $pages->{page}, $num_rows) + $self->{report_numheaders} - 1;
+ $self->{display_rows} = [
+ $first_row_header
+ ..
+ $last_row_header,
+ $first_row_data
+ ..
+ $last_row_data
+ ];
+
+ my @query = (
+ csv_import_report_id => $report_id,
+ or => [
+ and => [
+ row => { ge => $first_row_header },
+ row => { le => $last_row_header },
+ ],
+ and => [
+ row => { ge => $first_row_data },
+ row => { le => $last_row_data },
+ ]
+ ]
+ );
+
+ 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', { layout => !($params{no_layout} || $::form->{no_layout}) });
+}
+
+sub action_add_empty_mapping_line {
+ my ($self) = @_;
+
+ $self->profile_from_form;
+ $self->setup_help;
+
+ $self->js
+ ->append('#csv_import_mappings', $self->render('csv_import/_mapping_item', { layout => 0, output => 0 }))
+ ->hide('#mapping_empty')
+ ->render;
+}
+
+sub action_add_mapping_from_upload {
+ my ($self) = @_;
+
+ if ($::form->{tmp_profile_id}) {
+ $self->profile_from_form(SL::DB::CsvImportProfile->new(id => $::form->{tmp_profile_id})->load);
+ } else {
+ $self->profile_from_form;
+ }
+ $self->setup_help;
+
+ my $file_name;
+ if ($self->profile->get('file_name')) {
+ $file_name = $self->profile->get('file_name');
+ } else {
+ $self->js
+ ->flash('error', t8('No file has been uploaded yet.'))
+ ->render;
+ return;
+ }
+
+ my $file = SL::SessionFile->new($file_name, mode => '<', encoding => $self->profile->get('charset'));
+ if (!$file->fh) {
+ $self->js
+ ->flash('error', t8('No file has been uploaded yet.'))
+ ->render;
+ return;
+ }
+
+ my $csv = SL::Helper::Csv->new(
+ file => $file->file_name,
+ map { $_ => $self->profile->get($_) } qw(sep_char escape_char quote_char),
+ );
+
+ $csv->_open_file;
+ my $header = $csv->check_header;
+
+ for my $field (@$header) {
+ next if $self->mappings_for_profile->{$field};
+ $self->js->append(
+ '#csv_import_mappings',
+ $self->render('csv_import/_mapping_item', { layout => 0, output => 0 }, item => { from => $field }),
+ );
+ }
+
+ $self->js
+ ->hide('#mapping_empty')
+ ->render;
+}
+
+