Feature #22913 » 22913_auto_mapping_v2.patch
app/controllers/imports_controller.rb | ||
---|---|---|
65 | 65 | |
66 | 66 |
def mapping |
67 | 67 |
@custom_fields = @import.mappable_custom_fields |
68 |
auto_map_fields if @import.mapping.empty? |
|
68 | 69 | |
69 | 70 |
if request.post? |
70 | 71 |
respond_to do |format| |
... | ... | |
159 | 160 |
type && type < Import ? type : nil |
160 | 161 |
end |
161 | 162 |
end |
163 | ||
164 |
def auto_map_fields |
|
165 |
@import.settings['mapping'] = {} |
|
166 |
mappings = @import.mapping |
|
167 |
headers = @import.headers |
|
168 | ||
169 |
# Core fields |
|
170 |
import_type::AUTO_MAPPABLE_FIELDS.each do |field_nm, label_nm| |
|
171 |
next if mappings.include?(field_nm) |
|
172 |
header_column = l(label_nm) |
|
173 |
next if headers.exclude?(header_column) |
|
174 |
mappings[field_nm] = headers.index(header_column) |
|
175 |
end |
|
176 | ||
177 |
# Custom fields |
|
178 |
@custom_fields.each do |field| |
|
179 |
field_nm = "cf_#{field.id}" |
|
180 |
next if mappings.include?(field_nm) |
|
181 |
header_column = field.name |
|
182 |
next if headers.exclude?(header_column) |
|
183 |
mappings[field_nm] = headers.index(header_column) |
|
184 |
end |
|
185 |
end |
|
162 | 186 |
end |
app/models/import.rb | ||
---|---|---|
37 | 37 |
'%d.%m.%Y', |
38 | 38 |
'%d-%m-%Y' |
39 | 39 |
] |
40 |
AUTO_MAPPABLE_FIELDS = {} |
|
40 | 41 | |
41 | 42 |
def self.menu_item |
42 | 43 |
nil |
app/models/issue_import.rb | ||
---|---|---|
18 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
19 | 19 | |
20 | 20 |
class IssueImport < Import |
21 |
AUTO_MAPPABLE_FIELDS = { |
|
22 |
'tracker' => 'field_tracker', |
|
23 |
'subject' => 'field_subject', |
|
24 |
'description' => 'field_description', |
|
25 |
'status' => 'field_status', |
|
26 |
'priority' => 'field_priority', |
|
27 |
'category' => 'field_category', |
|
28 |
'assigned_to' => 'field_assigned_to', |
|
29 |
'fixed_version' => 'field_fixed_version', |
|
30 |
'is_private' => 'field_is_private', |
|
31 |
'parent_issue_id' => 'field_parent_issue', |
|
32 |
'start_date' => 'field_start_date', |
|
33 |
'due_date' => 'field_due_date', |
|
34 |
'estimated_hours' => 'field_estimated_hours', |
|
35 |
'done_ratio' => 'field_done_ratio' |
|
36 |
} |
|
37 | ||
21 | 38 |
def self.menu_item |
22 | 39 |
:issues |
23 | 40 |
end |
app/models/time_entry_import.rb | ||
---|---|---|
18 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
19 | 19 | |
20 | 20 |
class TimeEntryImport < Import |
21 |
AUTO_MAPPABLE_FIELDS = { |
|
22 |
'activity' => 'field_activity', |
|
23 |
'user_id' => 'field_user', |
|
24 |
'issue_id' => 'field_issue', |
|
25 |
'spent_on' => 'field_spent_on', |
|
26 |
'hours' => 'field_hours', |
|
27 |
'comments' => 'field_comments' |
|
28 |
} |
|
29 | ||
21 | 30 |
def self.menu_item |
22 | 31 |
:time_entries |
23 | 32 |
end |
app/views/imports/_issues_fields_mapping.html.erb | ||
---|---|---|
7 | 7 |
:id => 'import_mapping_project_id' %> |
8 | 8 |
</p> |
9 | 9 |
<p> |
10 |
<label for="import_mapping_tracker"><%= l(:label_tracker) %></label>
|
|
10 |
<label for="import_mapping_tracker"><%= l(:field_tracker) %></label>
|
|
11 | 11 |
<%= mapping_select_tag @import, 'tracker', :required => true, |
12 | 12 |
:values => @import.allowed_target_trackers.sorted.map {|t| [t.name, t.id]} %> |
13 | 13 |
</p> |
... | ... | |
99 | 99 |
</p> |
100 | 100 |
</div> |
101 | 101 |
</div> |
102 |
test/fixtures/files/import_auto_mapping.csv | ||
---|---|---|
1 |
Column 0;Column 1;Column 2;Subject;Column 4;Database;Column 6 |
|
2 |
0;1;2;3;4;5;6 |
test/fixtures/files/import_time_entries_auto_mapping.csv | ||
---|---|---|
1 |
Column 0;Column 1;Activity;Column 3;Overtime;Column 5;Column 6 |
|
2 |
0;1;2;3;4;5;6 |
test/functional/imports_controller_test.rb | ||
---|---|---|
167 | 167 |
end |
168 | 168 |
end |
169 | 169 | |
170 |
def test_get_mapping_should_auto_select_by_column_name |
|
171 |
import = generate_import('import_auto_mapping.csv') |
|
172 |
import.settings = {'separator' => ';', 'wrapper'=> '"', 'encoding' => 'ISO-8859-1'} |
|
173 |
import.save! |
|
174 | ||
175 |
get :mapping, :params => { |
|
176 |
:id => import.to_param |
|
177 |
} |
|
178 |
assert_response :success |
|
179 | ||
180 |
assert_select 'select[name=?]', 'import_settings[mapping][subject]' do |
|
181 |
assert_select 'option[value="3"][selected="selected"]', :text => 'Subject' |
|
182 |
end |
|
183 |
assert_select 'select[name=?]', 'import_settings[mapping][cf_1]' do |
|
184 |
assert_select 'option[value="5"][selected="selected"]', :text => 'Database' |
|
185 |
end |
|
186 |
end |
|
187 | ||
170 | 188 |
def test_post_mapping_should_update_mapping |
171 | 189 |
import = generate_import('import_iso8859-1.csv') |
172 | 190 | |
... | ... | |
223 | 241 |
assert_select 'select[name=?]', 'import_settings[mapping][user_id]', 0 |
224 | 242 |
end |
225 | 243 | |
244 |
def test_get_mapping_time_entry_should_auto_select_by_column_name |
|
245 |
import = generate_time_entry_import('import_time_entries_auto_mapping.csv') |
|
246 |
import.settings = {'separator' => ";", 'wrapper' => '"', 'encoding' => "ISO-8859-1"} |
|
247 |
import.save! |
|
248 | ||
249 |
get :mapping, :params => { |
|
250 |
:id => import.to_param |
|
251 |
} |
|
252 |
assert_response :success |
|
253 | ||
254 |
assert_select 'select[name=?]', 'import_settings[mapping][activity]' do |
|
255 |
assert_select 'option[value="2"][selected="selected"]', :text => 'Activity' |
|
256 |
end |
|
257 |
assert_select 'select[name=?]', 'import_settings[mapping][cf_10]' do |
|
258 |
assert_select 'option[value="4"][selected="selected"]', :text => 'Overtime' |
|
259 |
end |
|
260 |
end |
|
261 | ||
226 | 262 |
def test_get_run |
227 | 263 |
import = generate_import_with_mapping |
228 | 264 |