diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index 633cc232c..07fd59629 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -65,6 +65,7 @@ class ImportsController < ApplicationController def mapping @custom_fields = @import.mappable_custom_fields + auto_map_fields if @import.mapping.empty? if request.post? respond_to do |format| @@ -159,4 +160,27 @@ class ImportsController < ApplicationController type && type < Import ? type : nil end end + + def auto_map_fields + @import.settings['mapping'] = {} + mappings = @import.mapping + headers = @import.headers + + # Core fields + import_type::AUTO_MAPPABLE_FIELDS.each do |field_nm, label_nm| + next if mappings.include?(field_nm) + header_column = l(label_nm) + next if headers.exclude?(header_column) + mappings[field_nm] = headers.index(header_column) + end + + # Custom fields + @custom_fields.each do |field| + field_nm = "cf_#{field.id}" + next if mappings.include?(field_nm) + header_column = field.name + next if headers.exclude?(header_column) + mappings[field_nm] = headers.index(header_column) + end + end end diff --git a/app/models/import.rb b/app/models/import.rb index 61b3553f3..7f2715bdb 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -37,6 +37,7 @@ class Import < ActiveRecord::Base '%d.%m.%Y', '%d-%m-%Y' ] + AUTO_MAPPABLE_FIELDS = {} def self.menu_item nil diff --git a/app/models/issue_import.rb b/app/models/issue_import.rb index 206c0bfd5..7021f5370 100644 --- a/app/models/issue_import.rb +++ b/app/models/issue_import.rb @@ -18,6 +18,23 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class IssueImport < Import + AUTO_MAPPABLE_FIELDS = { + 'tracker' => 'field_tracker', + 'subject' => 'field_subject', + 'description' => 'field_description', + 'status' => 'field_status', + 'priority' => 'field_priority', + 'category' => 'field_category', + 'assigned_to' => 'field_assigned_to', + 'fixed_version' => 'field_fixed_version', + 'is_private' => 'field_is_private', + 'parent_issue_id' => 'field_parent_issue', + 'start_date' => 'field_start_date', + 'due_date' => 'field_due_date', + 'estimated_hours' => 'field_estimated_hours', + 'done_ratio' => 'field_done_ratio' + } + def self.menu_item :issues end diff --git a/app/models/time_entry_import.rb b/app/models/time_entry_import.rb index 0ac4429f4..ef0905905 100644 --- a/app/models/time_entry_import.rb +++ b/app/models/time_entry_import.rb @@ -18,6 +18,15 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class TimeEntryImport < Import + AUTO_MAPPABLE_FIELDS = { + 'activity' => 'field_activity', + 'user_id' => 'field_user', + 'issue_id' => 'field_issue', + 'spent_on' => 'field_spent_on', + 'hours' => 'field_hours', + 'comments' => 'field_comments' + } + def self.menu_item :time_entries end diff --git a/app/views/imports/_issues_fields_mapping.html.erb b/app/views/imports/_issues_fields_mapping.html.erb index 05bf92e9a..67c538ab4 100644 --- a/app/views/imports/_issues_fields_mapping.html.erb +++ b/app/views/imports/_issues_fields_mapping.html.erb @@ -7,7 +7,7 @@ :id => 'import_mapping_project_id' %>

- + <%= mapping_select_tag @import, 'tracker', :required => true, :values => @import.allowed_target_trackers.sorted.map {|t| [t.name, t.id]} %>

@@ -99,4 +99,3 @@

- diff --git a/test/fixtures/files/import_auto_mapping.csv b/test/fixtures/files/import_auto_mapping.csv new file mode 100644 index 000000000..6d0ec6a8d --- /dev/null +++ b/test/fixtures/files/import_auto_mapping.csv @@ -0,0 +1,2 @@ +Column 0;Column 1;Column 2;Subject;Column 4;Database;Column 6 +0;1;2;3;4;5;6 diff --git a/test/fixtures/files/import_time_entries_auto_mapping.csv b/test/fixtures/files/import_time_entries_auto_mapping.csv new file mode 100644 index 000000000..d84658124 --- /dev/null +++ b/test/fixtures/files/import_time_entries_auto_mapping.csv @@ -0,0 +1,2 @@ +Column 0;Column 1;Activity;Column 3;Overtime;Column 5;Column 6 +0;1;2;3;4;5;6 diff --git a/test/functional/imports_controller_test.rb b/test/functional/imports_controller_test.rb index 6b22bb19a..16c2ac086 100644 --- a/test/functional/imports_controller_test.rb +++ b/test/functional/imports_controller_test.rb @@ -167,6 +167,24 @@ class ImportsControllerTest < Redmine::ControllerTest end end + def test_get_mapping_should_auto_select_by_column_name + import = generate_import('import_auto_mapping.csv') + import.settings = {'separator' => ';', 'wrapper'=> '"', 'encoding' => 'ISO-8859-1'} + import.save! + + get :mapping, :params => { + :id => import.to_param + } + assert_response :success + + assert_select 'select[name=?]', 'import_settings[mapping][subject]' do + assert_select 'option[value="3"][selected="selected"]', :text => 'Subject' + end + assert_select 'select[name=?]', 'import_settings[mapping][cf_1]' do + assert_select 'option[value="5"][selected="selected"]', :text => 'Database' + end + end + def test_post_mapping_should_update_mapping import = generate_import('import_iso8859-1.csv') @@ -223,6 +241,24 @@ class ImportsControllerTest < Redmine::ControllerTest assert_select 'select[name=?]', 'import_settings[mapping][user_id]', 0 end + def test_get_mapping_time_entry_should_auto_select_by_column_name + import = generate_time_entry_import('import_time_entries_auto_mapping.csv') + import.settings = {'separator' => ";", 'wrapper' => '"', 'encoding' => "ISO-8859-1"} + import.save! + + get :mapping, :params => { + :id => import.to_param + } + assert_response :success + + assert_select 'select[name=?]', 'import_settings[mapping][activity]' do + assert_select 'option[value="2"][selected="selected"]', :text => 'Activity' + end + assert_select 'select[name=?]', 'import_settings[mapping][cf_10]' do + assert_select 'option[value="4"][selected="selected"]', :text => 'Overtime' + end + end + def test_get_run import = generate_import_with_mapping