mirror of
https://github.com/redmine/redmine.git
synced 2025-11-18 03:00:52 +01:00
Make Tracker map-able for CSV import (#22951).
git-svn-id: http://svn.redmine.org/redmine/trunk@15490 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -57,11 +57,7 @@ class ImportsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def mapping
|
def mapping
|
||||||
issue = Issue.new
|
@custom_fields = @import.mappable_custom_fields
|
||||||
issue.project = @import.project
|
|
||||||
issue.tracker = @import.tracker
|
|
||||||
@attributes = issue.safe_attribute_names
|
|
||||||
@custom_fields = issue.editable_custom_field_values.map(&:custom_field)
|
|
||||||
|
|
||||||
if request.post?
|
if request.post?
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
|||||||
@@ -23,12 +23,16 @@ module ImportsHelper
|
|||||||
blank_text = options[:required] ? "-- #{l(:actionview_instancetag_blank_option)} --" : " ".html_safe
|
blank_text = options[:required] ? "-- #{l(:actionview_instancetag_blank_option)} --" : " ".html_safe
|
||||||
tags << content_tag('option', blank_text, :value => '')
|
tags << content_tag('option', blank_text, :value => '')
|
||||||
tags << options_for_select(import.columns_options, import.mapping[field])
|
tags << options_for_select(import.columns_options, import.mapping[field])
|
||||||
|
if values = options[:values]
|
||||||
|
tags << content_tag('option', '--', :disabled => true)
|
||||||
|
tags << options_for_select(values.map {|text, value| [text, "value:#{value}"]}, import.mapping[field])
|
||||||
|
end
|
||||||
tags
|
tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def mapping_select_tag(import, field, options={})
|
def mapping_select_tag(import, field, options={})
|
||||||
name = "import_settings[mapping][#{field}]"
|
name = "import_settings[mapping][#{field}]"
|
||||||
select_tag name, options_for_mapping_select(import, field, options)
|
select_tag name, options_for_mapping_select(import, field, options), :id => "import_mapping_#{field}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the options for the date_format setting
|
# Returns the options for the date_format setting
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ class IssueImport < Import
|
|||||||
end
|
end
|
||||||
|
|
||||||
def tracker
|
def tracker
|
||||||
tracker_id = mapping['tracker_id'].to_i
|
if mapping['tracker'].to_s =~ /\Avalue:(\d+)\z/
|
||||||
allowed_target_trackers.find_by_id(tracker_id) || allowed_target_trackers.first
|
tracker_id = $1.to_i
|
||||||
|
allowed_target_trackers.find_by_id(tracker_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true if missing categories should be created during the import
|
# Returns true if missing categories should be created during the import
|
||||||
@@ -57,6 +59,19 @@ class IssueImport < Import
|
|||||||
mapping['create_versions'] == '1'
|
mapping['create_versions'] == '1'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mappable_custom_fields
|
||||||
|
if tracker
|
||||||
|
issue = Issue.new
|
||||||
|
issue.project = project
|
||||||
|
issue.tracker = tracker
|
||||||
|
issue.editable_custom_field_values(user).map(&:custom_field)
|
||||||
|
elsif project
|
||||||
|
project.all_issue_custom_fields
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def build_object(row)
|
def build_object(row)
|
||||||
@@ -64,12 +79,20 @@ class IssueImport < Import
|
|||||||
issue.author = user
|
issue.author = user
|
||||||
issue.notify = false
|
issue.notify = false
|
||||||
|
|
||||||
|
tracker_id = nil
|
||||||
|
if tracker
|
||||||
|
tracker_id = tracker.id
|
||||||
|
elsif tracker_name = row_value(row, 'tracker')
|
||||||
|
tracker_id = allowed_target_trackers.named(tracker_name).first.try(:id)
|
||||||
|
end
|
||||||
|
|
||||||
attributes = {
|
attributes = {
|
||||||
'project_id' => mapping['project_id'],
|
'project_id' => mapping['project_id'],
|
||||||
'tracker_id' => mapping['tracker_id'],
|
'tracker_id' => tracker_id,
|
||||||
'subject' => row_value(row, 'subject'),
|
'subject' => row_value(row, 'subject'),
|
||||||
'description' => row_value(row, 'description')
|
'description' => row_value(row, 'description')
|
||||||
}
|
}
|
||||||
|
attributes
|
||||||
issue.send :safe_attributes=, attributes, user
|
issue.send :safe_attributes=, attributes, user
|
||||||
|
|
||||||
attributes = {}
|
attributes = {}
|
||||||
@@ -149,6 +172,11 @@ class IssueImport < Import
|
|||||||
end
|
end
|
||||||
|
|
||||||
issue.send :safe_attributes=, attributes, user
|
issue.send :safe_attributes=, attributes, user
|
||||||
|
|
||||||
|
if issue.tracker_id != tracker_id
|
||||||
|
issue.tracker_id = nil
|
||||||
|
end
|
||||||
|
|
||||||
issue
|
issue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<div class="splitcontent">
|
|
||||||
<div class="splitcontentleft">
|
|
||||||
<p>
|
<p>
|
||||||
<label><%= l(:label_project) %></label>
|
<label><%= l(:label_project) %></label>
|
||||||
<%= select_tag 'import_settings[mapping][project_id]',
|
<%= select_tag 'import_settings[mapping][project_id]',
|
||||||
options_for_select(project_tree_options_for_select(@import.allowed_target_projects, :selected => @import.project)),
|
options_for_select(project_tree_options_for_select(@import.allowed_target_projects, :selected => @import.project)),
|
||||||
:id => 'issue_project_id' %>
|
:id => 'import_mapping_project_id' %>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label><%= l(:label_tracker) %></label>
|
<label><%= l(:label_tracker) %></label>
|
||||||
<%= select_tag 'import_settings[mapping][tracker_id]',
|
<%= mapping_select_tag @import, 'tracker', :required => true,
|
||||||
options_for_select(@import.allowed_target_trackers.sorted.map {|t| [t.name, t.id]}, @import.tracker.try(:id)),
|
:values => @import.allowed_target_trackers.sorted.map {|t| [t.name, t.id]} %>
|
||||||
:id => 'issue_tracker_id' %>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div class="splitcontent">
|
||||||
|
<div class="splitcontentleft">
|
||||||
<p>
|
<p>
|
||||||
<label><%= l(:field_subject) %></label>
|
<label><%= l(:field_subject) %></label>
|
||||||
<%= mapping_select_tag @import, 'subject', :required => true %>
|
<%= mapping_select_tag @import, 'subject', :required => true %>
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<%= javascript_tag do %>
|
<%= javascript_tag do %>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#fields-mapping').on('change', '#issue_project_id, #issue_tracker_id', function(){
|
$('#fields-mapping').on('change', '#import_mapping_project_id, #import_mapping_tracker', function(){
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '<%= import_mapping_path(@import, :format => 'js') %>',
|
url: '<%= import_mapping_path(@import, :format => 'js') %>',
|
||||||
type: 'post',
|
type: 'post',
|
||||||
|
|||||||
8
test/fixtures/files/import_issues.csv
vendored
8
test/fixtures/files/import_issues.csv
vendored
@@ -1,4 +1,4 @@
|
|||||||
priority;subject;description;start_date;due_date;parent;private;progress;custom;version;category;user;estimated_hours
|
priority;subject;description;start_date;due_date;parent;private;progress;custom;version;category;user;estimated_hours;tracker
|
||||||
High;First;First description;2015-07-08;2015-08-25;;no;;PostgreSQL;;New category;dlopper;1
|
High;First;First description;2015-07-08;2015-08-25;;no;;PostgreSQL;;New category;dlopper;1;bug
|
||||||
Normal;Child 1;Child description;;;1;yes;10;MySQL;2.0;New category;;2
|
Normal;Child 1;Child description;;;1;yes;10;MySQL;2.0;New category;;2;feature request
|
||||||
Normal;Child of existing issue;Child description;;;#2;no;20;;2.1;Printing;;3
|
Normal;Child of existing issue;Child description;;;#2;no;20;;2.1;Printing;;3;bug
|
||||||
|
|||||||
|
@@ -235,7 +235,7 @@ module ObjectHelpers
|
|||||||
|
|
||||||
import.settings = {
|
import.settings = {
|
||||||
'separator' => ";", 'wrapper' => '"', 'encoding' => "UTF-8",
|
'separator' => ";", 'wrapper' => '"', 'encoding' => "UTF-8",
|
||||||
'mapping' => {'project_id' => '1', 'tracker_id' => '2', 'subject' => '1'}
|
'mapping' => {'project_id' => '1', 'tracker' => '13', 'subject' => '1'}
|
||||||
}
|
}
|
||||||
import.save!
|
import.save!
|
||||||
import
|
import
|
||||||
|
|||||||
@@ -58,6 +58,37 @@ class IssueImportTest < ActiveSupport::TestCase
|
|||||||
assert_equal 'New category', category.name
|
assert_equal 'New category', category.name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_mapping_with_fixed_tracker
|
||||||
|
import = generate_import_with_mapping
|
||||||
|
import.mapping.merge!('tracker' => 'value:2')
|
||||||
|
import.save!
|
||||||
|
|
||||||
|
issues = new_records(Issue, 3) { import.run }
|
||||||
|
assert_equal [2], issues.map(&:tracker_id).uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_mapping_with_mapped_tracker
|
||||||
|
import = generate_import_with_mapping
|
||||||
|
import.mapping.merge!('tracker' => '13')
|
||||||
|
import.save!
|
||||||
|
|
||||||
|
issues = new_records(Issue, 3) { import.run }
|
||||||
|
assert_equal [1, 2, 1], issues.map(&:tracker_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_should_not_import_with_default_tracker_when_tracker_is_invalid
|
||||||
|
Tracker.find_by_name('Feature request').update!(:name => 'Feature')
|
||||||
|
|
||||||
|
import = generate_import_with_mapping
|
||||||
|
import.mapping.merge!('tracker' => '13')
|
||||||
|
import.save!
|
||||||
|
import.run
|
||||||
|
|
||||||
|
assert_equal 1, import.unsaved_items.count
|
||||||
|
item = import.unsaved_items.first
|
||||||
|
assert_include "Tracker cannot be blank", item.message
|
||||||
|
end
|
||||||
|
|
||||||
def test_parent_should_be_set
|
def test_parent_should_be_set
|
||||||
import = generate_import_with_mapping
|
import = generate_import_with_mapping
|
||||||
import.mapping.merge!('parent_issue_id' => '5')
|
import.mapping.merge!('parent_issue_id' => '5')
|
||||||
@@ -101,7 +132,7 @@ class IssueImportTest < ActiveSupport::TestCase
|
|||||||
field = IssueCustomField.generate!(:field_format => 'date', :is_for_all => true, :trackers => Tracker.all)
|
field = IssueCustomField.generate!(:field_format => 'date', :is_for_all => true, :trackers => Tracker.all)
|
||||||
import = generate_import_with_mapping('import_dates.csv')
|
import = generate_import_with_mapping('import_dates.csv')
|
||||||
import.settings.merge!('date_format' => Import::DATE_FORMATS[1])
|
import.settings.merge!('date_format' => Import::DATE_FORMATS[1])
|
||||||
import.mapping.merge!('subject' => '0', 'start_date' => '1', 'due_date' => '2', "cf_#{field.id}" => '3')
|
import.mapping.merge!('tracker' => 'value:1', 'subject' => '0', 'start_date' => '1', 'due_date' => '2', "cf_#{field.id}" => '3')
|
||||||
import.save!
|
import.save!
|
||||||
|
|
||||||
issue = new_record(Issue) { import.run } # only 1 valid issue
|
issue = new_record(Issue) { import.run } # only 1 valid issue
|
||||||
|
|||||||
Reference in New Issue
Block a user