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 | |