summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2007-11-17 17:45:21 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2007-11-17 17:45:21 +0000
commite2c606e974593c04d8544d3319453bdfda7982d8 (patch)
tree26ec97acddcc05cf7060ed336c07865e75a879f4
parent9ad79612fed43e70f318aed2f90d8b29ad667a77 (diff)
downloadredmine-e2c606e974593c04d8544d3319453bdfda7982d8.tar.gz
redmine-e2c606e974593c04d8544d3319453bdfda7982d8.zip
Fixed: Update of time entry fails when the issue has been moved to an other project.
Fixed: Error when moving an issue without changing its tracker (Postgresql). git-svn-id: http://redmine.rubyforge.org/svn/trunk@909 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r--app/controllers/projects_controller.rb27
-rw-r--r--app/models/issue.rb26
-rw-r--r--app/views/issues/index.rhtml2
-rw-r--r--public/images/true.pngbin455 -> 1094 bytes
-rw-r--r--test/unit/issue_test.rb13
5 files changed, 49 insertions, 19 deletions
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 092e1dd00..289b34e24 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -299,29 +299,22 @@ class ProjectsController < ApplicationController
# admin is allowed to move issues to any active (visible) project
@projects = Project.find(:all, :conditions => Project.visible_by(User.current), :order => 'name')
else
- User.current.memberships.each {|m| @projects << m.project if m.role.allowed_to?(:controller => 'projects', :action => 'move_issues')}
+ User.current.memberships.each {|m| @projects << m.project if m.role.allowed_to?(:move_issues)}
end
# issue can be moved to any tracker
@trackers = Tracker.find(:all)
if request.post? && params[:new_project_id] && @projects.collect(&:id).include?(params[:new_project_id].to_i) && params[:new_tracker_id]
new_project = Project.find_by_id(params[:new_project_id])
- new_tracker = Tracker.find_by_id(params[:new_tracker_id])
- @issues.each do |i|
- if new_project && i.project_id != new_project.id
- # issue is moved to another project
- i.category = nil
- i.fixed_version = nil
- # delete issue relations
- i.relations_from.clear
- i.relations_to.clear
- i.project = new_project
- end
- if new_tracker
- i.tracker = new_tracker
- end
- i.save
+ new_tracker = params[:new_tracker_id].blank? ? nil : Tracker.find_by_id(params[:new_tracker_id])
+ unsaved_issue_ids = []
+ @issues.each do |issue|
+ unsaved_issue_ids << issue.id unless issue.move_to(new_project, new_tracker)
+ end
+ if unsaved_issue_ids.empty?
+ flash[:notice] = l(:notice_successful_update) unless @issues.empty?
+ else
+ flash[:error] = l(:notice_failed_to_save_issues, unsaved_issue_ids.size, @issues.size, '#' + unsaved_issue_ids.join(', #'))
end
- flash[:notice] = l(:notice_successful_update)
redirect_to :controller => 'issues', :action => 'index', :project_id => @project
end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 0d2d6fc0d..60cca4051 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -61,6 +61,32 @@ class Issue < ActiveRecord::Base
self
end
+ # Move an issue to a new project and tracker
+ def move_to(new_project, new_tracker = nil)
+ transaction do
+ if new_project && project_id != new_project.id
+ # delete issue relations
+ self.relations_from.clear
+ self.relations_to.clear
+ # issue is moved to another project
+ self.category = nil
+ self.fixed_version = nil
+ self.project = new_project
+ end
+ if new_tracker
+ self.tracker = new_tracker
+ end
+ if save
+ # Manually update project_id on related time entries
+ TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id})
+ else
+ rollback_db_transaction
+ return false
+ end
+ end
+ return true
+ end
+
def priority_id=(pid)
self.priority = nil
write_attribute(:priority_id, pid)
diff --git a/app/views/issues/index.rhtml b/app/views/issues/index.rhtml
index fa77cb78c..de0fd4add 100644
--- a/app/views/issues/index.rhtml
+++ b/app/views/issues/index.rhtml
@@ -10,7 +10,7 @@
{ :url => { :set_filter => 1 },
:update => "content",
:with => "Form.serialize('query_form')"
- }, :class => 'icon icon-edit' %>
+ }, :class => 'icon icon-checked' %>
<%= link_to_remote l(:button_clear),
{ :url => { :set_filter => 1 },
diff --git a/public/images/true.png b/public/images/true.png
index 929c605ff..7cac1eb8c 100644
--- a/public/images/true.png
+++ b/public/images/true.png
Binary files differ
diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb
index 5ddd4bde4..6ffbe0a8b 100644
--- a/test/unit/issue_test.rb
+++ b/test/unit/issue_test.rb
@@ -18,7 +18,7 @@
require File.dirname(__FILE__) + '/../test_helper'
class IssueTest < Test::Unit::TestCase
- fixtures :projects, :users, :members, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values
+ fixtures :projects, :users, :members, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :time_entries
def test_category_based_assignment
issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
@@ -59,4 +59,15 @@ class IssueTest < Test::Unit::TestCase
assert issue2.reload.closed?
assert issue3.reload.closed?
end
+
+ def test_move_to_another_project
+ issue = Issue.find(1)
+ assert issue.move_to(Project.find(2))
+ issue.reload
+ assert_equal 2, issue.project_id
+ # Category removed
+ assert_nil issue.category
+ # Make sure time entries were move to the target project
+ assert_equal 2, issue.time_entries.first.project_id
+ end
end