X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FCsvImport.pm;h=790d477cf21c19a5e6cd37df0118d1be9363fcef;hb=f9a93e326337ed219de49f575c02e5a8cb36a1b6;hp=50b5e4d050b63212e5253d60bac3c36cb376299e;hpb=efb9a24f2252104ab4af5c25334119d7c5c70a8c;p=kivitendo-erp.git diff --git a/SL/Controller/CsvImport.pm b/SL/Controller/CsvImport.pm index 50b5e4d05..790d477cf 100644 --- a/SL/Controller/CsvImport.pm +++ b/SL/Controller/CsvImport.pm @@ -13,9 +13,13 @@ use SL::SessionFile; use SL::Controller::CsvImport::Contact; use SL::Controller::CsvImport::CustomerVendor; use SL::Controller::CsvImport::Part; +use SL::Controller::CsvImport::Inventory; use SL::Controller::CsvImport::Shipto; use SL::Controller::CsvImport::Project; use SL::Controller::CsvImport::Order; +use SL::Controller::CsvImport::ARTransaction; +use SL::JSON; +use SL::Controller::CsvImport::BankTransaction; use SL::BackgroundJob::CsvImport; use SL::System::TaskServer; @@ -27,8 +31,8 @@ use parent qw(SL::Controller::Base); use Rose::Object::MakeMethods::Generic ( scalar => [ qw(type profile file all_profiles all_charsets sep_char all_sep_chars quote_char all_quote_chars escape_char all_escape_chars all_buchungsgruppen all_units - import_status errors headers raw_data_headers info_headers data num_imported num_importable displayable_columns file) ], - 'scalar --get_set_init' => [ qw(worker task_server) ], + import_status errors headers raw_data_headers info_headers data num_importable displayable_columns file all_taxzones) ], + 'scalar --get_set_init' => [ qw(worker task_server num_imported mappings) ], 'array' => [ progress_tracker => { }, add_progress_tracker => { interface => 'add', hash_key => 'progress_tracker' }, @@ -97,7 +101,7 @@ sub action_result { $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.', $first_error->[2], $first_error->[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}) { @@ -209,6 +213,53 @@ sub action_report { $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) = @_; + + $self->profile_from_form; + $self->setup_help; + + my $file = SL::SessionFile->new($self->csv_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; +} + # # filters @@ -221,7 +272,7 @@ sub check_auth { sub check_type { my ($self) = @_; - die "Invalid CSV import type" if none { $_ eq $::form->{profile}->{type} } qw(parts customers_vendors addresses contacts projects orders); + die "Invalid CSV import type" if none { $_ eq $::form->{profile}->{type} } qw(parts inventories customers_vendors addresses contacts projects orders bank_transactions ar_transactions); $self->type($::form->{profile}->{type}); } @@ -263,10 +314,17 @@ sub render_inputs { : $self->type eq 'addresses' ? $::locale->text('CSV import: shipping addresses') : $self->type eq 'contacts' ? $::locale->text('CSV import: contacts') : $self->type eq 'parts' ? $::locale->text('CSV import: parts and services') + : $self->type eq 'inventories' ? $::locale->text('CSV import: inventories') : $self->type eq 'projects' ? $::locale->text('CSV import: projects') : $self->type eq 'orders' ? $::locale->text('CSV import: orders') + : $self->type eq 'bank_transactions' ? $::locale->text('CSV import: bank transactions') + : $self->type eq 'ar_transactions' ? $::locale->text('CSV import: ar transactions') : die; + if ($self->{type} eq 'customers_vendors' or $self->{type} eq 'orders' or $self->{type} eq 'ar_transactions' ) { + $self->all_taxzones(SL::DB::Manager::TaxZone->get_all_sorted(query => [ obsolete => 0 ])); + }; + if ($self->{type} eq 'parts') { $self->all_buchungsgruppen(SL::DB::Manager::Buchungsgruppe->get_all_sorted); $self->all_units(SL::DB::Manager::Unit->get_all_sorted); @@ -280,7 +338,11 @@ sub render_inputs { sub test_and_import_deferred { my ($self, %params) = @_; - $self->profile_from_form; + if ( $::form->{force_profile} && $::form->{profile}->{id} ) { + $self->load_default_profile; + } else { + $self->profile_from_form; + }; if ($::form->{file}) { my $file = SL::SessionFile->new($self->csv_file_name, mode => '>'); @@ -308,11 +370,15 @@ sub test_and_import_deferred { $self->task_server->start; } - flash('info', $::locale->text('Your import is beig processed.')); + flash('info', $::locale->text('Your import is being processed.')); $self->{deferred} = 1; - $self->render_inputs; + if ($::request->type eq 'json') { + $self->render(\ SL::JSON::to_json($self->{background_job}->as_tree), { type => 'json' }) + } else { + $self->render_inputs; + } } sub test_and_import { @@ -353,6 +419,8 @@ sub load_default_profile { $profile ||= SL::DB::CsvImportProfile->new(type => $self->{type}, login => $::myconfig{login}); $self->profile($profile); + $self->mappings(SL::JSON::from_json($self->profile->get('json_mappings'))) if $self->profile->get('json_mappings'); + $self->worker->set_profile_defaults; $self->profile->set_defaults; } @@ -363,6 +431,7 @@ sub load_all_profiles { where => [ type => $self->type, login => $::myconfig{login}, + '!name' => '', ], sort_by => 'name')); } @@ -395,6 +464,9 @@ sub profile_from_form { $self->profile->assign_attributes(%{ $::form->{profile} }); $self->profile->settings(map({ { key => $_, value => $::form->{settings}->{$_} } } keys %{ $::form->{settings} }), @settings); + + $self->profile->set('json_mappings', JSON::to_json($self->mappings)); + $self->profile->set_defaults; } @@ -414,17 +486,17 @@ sub char_map { } sub save_report { - my ($self, $report_id) = @_; + my ($self, %params) = @_; if ($self->worker->is_multiplexed) { - return $self->save_report_multi($report_id); + return $self->save_report_multi(%params); } else { - return $self->save_report_single($report_id); + return $self->save_report_single(%params); } } sub save_report_single { - my ($self, $report_id) = @_; + my ($self, %params) = @_; $self->track_progress(phase => 'building report', progress => 0); @@ -432,7 +504,7 @@ sub save_report_single { $clone_profile->save; # weird bug. if this isn't saved before adding it to the report, it will default back to the last profile. my $report = SL::DB::CsvImportReport->new( - session_id => $::auth->create_or_refresh_session, + session_id => $params{session_id}, profile => $clone_profile, type => $self->type, file => '', @@ -494,7 +566,7 @@ sub save_report_single { } sub save_report_multi { - my ($self, $report_id) = @_; + my ($self, %params) = @_; $self->track_progress(phase => 'building report', progress => 0); @@ -502,7 +574,7 @@ sub save_report_multi { $clone_profile->save; # weird bug. if this isn't saved before adding it to the report, it will default back to the last profile. my $report = SL::DB::CsvImportReport->new( - session_id => $::auth->create_or_refresh_session, + session_id => $params{session_id}, profile => $clone_profile, type => $self->type, file => '', @@ -603,11 +675,16 @@ sub init_worker { : $self->{type} eq 'contacts' ? SL::Controller::CsvImport::Contact->new(@args) : $self->{type} eq 'addresses' ? SL::Controller::CsvImport::Shipto->new(@args) : $self->{type} eq 'parts' ? SL::Controller::CsvImport::Part->new(@args) + : $self->{type} eq 'inventories' ? SL::Controller::CsvImport::Inventory->new(@args) : $self->{type} eq 'projects' ? SL::Controller::CsvImport::Project->new(@args) : $self->{type} eq 'orders' ? SL::Controller::CsvImport::Order->new(@args) + : $self->{type} eq 'bank_transactions' ? SL::Controller::CsvImport::BankTransaction->new(@args) + : $self->{type} eq 'ar_transactions' ? SL::Controller::CsvImport::ARTransaction->new(@args) : die "Program logic error"; } +sub init_num_imported { 0 } + sub setup_help { my ($self) = @_; @@ -638,4 +715,12 @@ sub check_task_server { 1; } +sub mappings_for_profile { + +{ map { $_->{from} => $_->{to} } @{ $_[0]->mappings } } +} + +sub init_mappings { + [ grep { $_->{from} } @{ $::form->{mappings} || [] } ] +} + 1;