summaryrefslogtreecommitdiffstats
path: root/app/models/issue_import.rb
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2015-08-14 08:20:32 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2015-08-14 08:20:32 +0000
commit035edd39c422c9434147a1b0ac457cb9383c9b5b (patch)
tree4b25e158e04068c535e828c04f336c769ac9db9c /app/models/issue_import.rb
parent763d5dddde2c7dda03fe529c9dfe0d553669c277 (diff)
downloadredmine-035edd39c422c9434147a1b0ac457cb9383c9b5b.tar.gz
redmine-035edd39c422c9434147a1b0ac457cb9383c9b5b.zip
Import issues from CSV file (#950).
git-svn-id: http://svn.redmine.org/redmine/trunk@14493 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app/models/issue_import.rb')
-rw-r--r--app/models/issue_import.rb145
1 files changed, 145 insertions, 0 deletions
diff --git a/app/models/issue_import.rb b/app/models/issue_import.rb
new file mode 100644
index 000000000..2ff127605
--- /dev/null
+++ b/app/models/issue_import.rb
@@ -0,0 +1,145 @@
+# Redmine - project management software
+# Copyright (C) 2006-2015 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class IssueImport < Import
+
+ # Returns the objects that were imported
+ def saved_objects
+ object_ids = saved_items.pluck(:obj_id)
+ objects = Issue.where(:id => object_ids).order(:id).preload(:tracker, :priority, :status)
+ end
+
+ # Returns a scope of projects that user is allowed to
+ # import issue to
+ def allowed_target_projects
+ Project.allowed_to(user, :import_issues)
+ end
+
+ def project
+ project_id = mapping['project_id'].to_i
+ allowed_target_projects.find_by_id(project_id) || allowed_target_projects.first
+ end
+
+ # Returns a scope of trackers that user is allowed to
+ # import issue to
+ def allowed_target_trackers
+ project.trackers
+ end
+
+ def tracker
+ tracker_id = mapping['tracker_id'].to_i
+ allowed_target_trackers.find_by_id(tracker_id) || allowed_target_trackers.first
+ end
+
+ # Returns true if missing categories should be created during the import
+ def create_categories?
+ user.allowed_to?(:manage_categories, project) &&
+ mapping['create_categories'] == '1'
+ end
+
+ # Returns true if missing versions should be created during the import
+ def create_versions?
+ user.allowed_to?(:manage_versions, project) &&
+ mapping['create_versions'] == '1'
+ end
+
+ private
+
+ def build_object(row)
+ issue = Issue.new
+ issue.author = user
+ issue.notify = false
+
+ attributes = {
+ 'project_id' => mapping['project_id'],
+ 'tracker_id' => mapping['tracker_id'],
+ 'subject' => row_value(row, 'subject'),
+ 'description' => row_value(row, 'description')
+ }
+ issue.send :safe_attributes=, attributes, user
+
+ attributes = {}
+ if priority_name = row_value(row, 'priority')
+ if priority_id = IssuePriority.active.named(priority_name).first.try(:id)
+ attributes['priority_id'] = priority_id
+ end
+ end
+ if issue.project && category_name = row_value(row, 'category')
+ if category = issue.project.issue_categories.named(category_name).first
+ attributes['category_id'] = category.id
+ elsif create_categories?
+ category = issue.project.issue_categories.build
+ category.name = category_name
+ if category.save
+ attributes['category_id'] = category.id
+ end
+ end
+ end
+ if assignee_name = row_value(row, 'assigned_to')
+ if assignee = issue.assignable_users.detect {|u| u.name.downcase == assignee_name.downcase}
+ attributes['assigned_to_id'] = assignee.id
+ end
+ end
+ if issue.project && version_name = row_value(row, 'fixed_version')
+ if version = issue.project.versions.detect {|v| v.name.downcase == version_name.downcase}
+ attributes['fixed_version_id'] = version.id
+ elsif create_versions?
+ version = issue.project.versions.build
+ version.name = version_name
+ if version.save
+ attributes['fixed_version_id'] = version.id
+ end
+ end
+ end
+ if is_private = row_value(row, 'is_private')
+ if yes?(is_private)
+ attributes['is_private'] = '1'
+ end
+ end
+ if parent_issue_id = row_value(row, 'parent_issue_id')
+ if parent_issue_id =~ /\A(#)?(\d+)\z/
+ parent_issue_id = $2
+ if $1
+ attributes['parent_issue_id'] = parent_issue_id
+ elsif issue_id = items.where(:position => parent_issue_id).first.try(:obj_id)
+ attributes['parent_issue_id'] = issue_id
+ end
+ else
+ attributes['parent_issue_id'] = parent_issue_id
+ end
+ end
+ if start_date = row_value(row, 'start_date')
+ attributes['start_date'] = start_date
+ end
+ if due_date = row_value(row, 'due_date')
+ attributes['due_date'] = due_date
+ end
+ if done_ratio = row_value(row, 'done_ratio')
+ attributes['done_ratio'] = done_ratio
+ end
+
+ attributes['custom_field_values'] = issue.custom_field_values.inject({}) do |h, v|
+ if value = row_value(row, "cf_#{v.custom_field.id}")
+ h[v.custom_field.id.to_s] = v.custom_field.value_from_keyword(value, issue)
+ end
+ h
+ end
+
+ issue.send :safe_attributes=, attributes, user
+ issue
+ end
+end