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
This commit is contained in:
Jean-Philippe Lang 2007-11-17 17:45:21 +00:00
parent 9ad79612fe
commit e2c606e974
5 changed files with 49 additions and 19 deletions

View File

@ -299,29 +299,22 @@ class ProjectsController < ApplicationController
# admin is allowed to move issues to any active (visible) project # admin is allowed to move issues to any active (visible) project
@projects = Project.find(:all, :conditions => Project.visible_by(User.current), :order => 'name') @projects = Project.find(:all, :conditions => Project.visible_by(User.current), :order => 'name')
else 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 end
# issue can be moved to any tracker # issue can be moved to any tracker
@trackers = Tracker.find(:all) @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] 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_project = Project.find_by_id(params[:new_project_id])
new_tracker = Tracker.find_by_id(params[:new_tracker_id]) new_tracker = params[:new_tracker_id].blank? ? nil : Tracker.find_by_id(params[:new_tracker_id])
@issues.each do |i| unsaved_issue_ids = []
if new_project && i.project_id != new_project.id @issues.each do |issue|
# issue is moved to another project unsaved_issue_ids << issue.id unless issue.move_to(new_project, new_tracker)
i.category = nil
i.fixed_version = nil
# delete issue relations
i.relations_from.clear
i.relations_to.clear
i.project = new_project
end end
if new_tracker if unsaved_issue_ids.empty?
i.tracker = new_tracker 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 end
i.save
end
flash[:notice] = l(:notice_successful_update)
redirect_to :controller => 'issues', :action => 'index', :project_id => @project redirect_to :controller => 'issues', :action => 'index', :project_id => @project
end end
end end

View File

@ -61,6 +61,32 @@ class Issue < ActiveRecord::Base
self self
end 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) def priority_id=(pid)
self.priority = nil self.priority = nil
write_attribute(:priority_id, pid) write_attribute(:priority_id, pid)

View File

@ -10,7 +10,7 @@
{ :url => { :set_filter => 1 }, { :url => { :set_filter => 1 },
:update => "content", :update => "content",
:with => "Form.serialize('query_form')" :with => "Form.serialize('query_form')"
}, :class => 'icon icon-edit' %> }, :class => 'icon icon-checked' %>
<%= link_to_remote l(:button_clear), <%= link_to_remote l(:button_clear),
{ :url => { :set_filter => 1 }, { :url => { :set_filter => 1 },

Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -18,7 +18,7 @@
require File.dirname(__FILE__) + '/../test_helper' require File.dirname(__FILE__) + '/../test_helper'
class IssueTest < Test::Unit::TestCase 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 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) 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 issue2.reload.closed?
assert issue3.reload.closed? assert issue3.reload.closed?
end 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 end