Skip to content

Commit b3e4214

Browse files
committed
Add the ability to change the author of an issue (#1739).
Patch by Vladimir Kovacik, Jiri Stepanek, Aighan Pacobilch, Olivier Houdas, Takenori TAKAKI, and Mizuki ISHIKAWA. git-svn-id: https://svn.redmine.org/redmine/trunk@21958 e93f8b46-1217-0410-a6f0-8f06a7374b81
1 parent f972b5b commit b3e4214

File tree

12 files changed

+152
-3
lines changed

12 files changed

+152
-3
lines changed

app/helpers/issues_helper.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ def show_detail(detail, no_html=false, options={})
534534
old_value = format_date(detail.old_value.to_date) if detail.old_value
535535

536536
when 'project_id', 'status_id', 'tracker_id', 'assigned_to_id',
537-
'priority_id', 'category_id', 'fixed_version_id'
537+
'priority_id', 'category_id', 'fixed_version_id', 'author_id'
538538
value = find_name_by_reflection(field, detail.value)
539539
old_value = find_name_by_reflection(field, detail.old_value)
540540

@@ -778,4 +778,23 @@ def projects_for_select(issue)
778778
projects
779779
end
780780
end
781+
782+
def author_options_for_select(issue, project)
783+
users = issue.assignable_users.select {|m| m.is_a?(User) && m.allowed_to?(:add_issues, project) }
784+
785+
if issue.new_record?
786+
if users.include?(User.current)
787+
principals_options_for_select(users, issue.author)
788+
else
789+
principals_options_for_select([User.current] + users)
790+
end
791+
elsif issue.persisted?
792+
if users.include?(issue.author)
793+
principals_options_for_select(users, issue.author)
794+
else
795+
author_principal = Principal.find(issue.author_id)
796+
principals_options_for_select([author_principal] + users, author_principal)
797+
end
798+
end
799+
end
781800
end

app/models/issue.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class Issue < ActiveRecord::Base
111111
before_validation :clear_disabled_fields
112112
before_save :close_duplicates, :update_done_ratio_from_issue_status,
113113
:force_updated_on_change, :update_closed_on
114+
before_create :set_author_journal
114115
after_save do |issue|
115116
if !issue.saved_change_to_id? && issue.saved_change_to_project_id?
116117
issue.send :after_project_change
@@ -519,6 +520,9 @@ def estimated_hours=(h)
519520
safe_attributes(
520521
'deleted_attachment_ids',
521522
:if => lambda {|issue, user| issue.attachments_deletable?(user)})
523+
safe_attributes(
524+
'author_id',
525+
:if => lambda {|issue, user| user.allowed_to?(:change_issue_author, issue.project)})
522526

523527
def safe_attribute_names(user=nil)
524528
names = super
@@ -2020,6 +2024,14 @@ def create_parent_issue_journal
20202024
end
20212025
end
20222026

2027+
def set_author_journal
2028+
return unless new_record?
2029+
return unless self.author.present? && User.current.present? && self.author != User.current
2030+
2031+
self.init_journal(User.current)
2032+
self.current_journal.__send__(:add_attribute_detail, 'author_id', User.current.id, self.author.id)
2033+
end
2034+
20232035
def send_notification
20242036
if notify? && Setting.notified_events.include?('issue_added')
20252037
Mailer.deliver_issue_add(self)

app/views/issues/_attributes.html.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
<div class="splitcontent">
44
<div class="splitcontentleft">
55
<% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %>
6+
<% if User.current.allowed_to?(:change_issue_author, @project) %>
7+
<p><%= f.select :author_id, author_options_for_select(@issue, @project), :include_blank => false, :required => true %></p>
8+
<% end %>
69
<p>
710
<%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
811
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" %>

config/locales/en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ en:
541541
permission_view_private_notes: View private notes
542542
permission_set_notes_private: Set notes as private
543543
permission_delete_issues: Delete issues
544+
permission_change_issue_author: Change issue author
544545
permission_manage_public_queries: Manage public queries
545546
permission_save_queries: Save queries
546547
permission_view_gantt: View gantt chart

lib/redmine/preparation.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def self.prepare
7272
map.permission :view_private_notes, {}, :read => true, :require => :member
7373
map.permission :set_notes_private, {}, :require => :member
7474
map.permission :delete_issues, {:issues => :destroy}, :require => :member
75+
map.permission :change_issue_author, {:issues => [:edit, :update]}
7576
map.permission :mention_users, {}
7677
# Watchers
7778
map.permission :view_issue_watchers, {}, :read => true

test/functional/issues_controller_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8306,6 +8306,7 @@ def test_destroy_issues_from_different_projects
83068306
end
83078307

83088308
def test_destroy_child_issue
8309+
User.current = User.find(1)
83098310
parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
83108311
child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
83118312
assert child.is_descendant_of?(parent.reload)

test/functional/versions_controller_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def test_index_should_prepend_shared_versions
103103
end
104104

105105
def test_index_should_show_issue_assignee
106+
User.current = User.find_by_login('jsmith')
106107
with_settings :gravatar_enabled => '1' do
107108
Issue.generate!(:project_id => 3, :fixed_version_id => 4, :assigned_to => User.find_by_login('jsmith'))
108109
Issue.generate!(:project_id => 3, :fixed_version_id => 4)

test/helpers/issues_helper_test.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,4 +465,62 @@ def test_render_relations_stats
465465
assert_include "<a href=\"/issues?issue_id=#{open_issue.id}%2C#{closed_issue.id}&amp;set_filter=true&amp;status_id=o\">1 open</a>", html
466466
assert_include "<a href=\"/issues?issue_id=#{open_issue.id}%2C#{closed_issue.id}&amp;set_filter=true&amp;status_id=c\">1 closed</a>", html
467467
end
468+
469+
def test_author_options_for_select_if_new_record_and_users_includes_current_user
470+
User.current = User.find(2)
471+
issue = Issue.new(project_id: 1)
472+
assignable_users = [User.find(3), User.find(2)]
473+
474+
assert_includes assignable_users, User.current
475+
assert_equal(
476+
principals_options_for_select(assignable_users, nil),
477+
author_options_for_select(issue, issue.project))
478+
end
479+
480+
def test_author_options_for_select_if_new_record_and_users_not_includes_current_user
481+
User.current = User.find(1)
482+
issue = Issue.new(project_id: 1)
483+
assignable_users = [User.find(3), User.find(2)]
484+
assert_not_includes assignable_users, User.current
485+
486+
assert_equal(
487+
principals_options_for_select([User.current] + assignable_users, nil),
488+
author_options_for_select(issue, issue.project))
489+
end
490+
491+
def test_author_options_for_select_if_persisted_record_and_users_includes_author
492+
User.current = User.find(2)
493+
issue = Issue.find(1)
494+
issue.update(author_id: 2)
495+
assignable_users = [User.find(3), User.find(2)]
496+
497+
assert_includes assignable_users, issue.author
498+
assert_equal(
499+
principals_options_for_select(assignable_users, issue.author),
500+
author_options_for_select(issue, issue.project))
501+
end
502+
503+
def test_author_options_for_select_if_persisted_record_and_users_not_includes_author
504+
User.current = User.find(2)
505+
issue = Issue.find(1)
506+
issue.update(author_id: 1)
507+
assignable_users = [User.find(3), User.find(2)]
508+
509+
assert_not_includes assignable_users, issue.author
510+
assert_equal(
511+
principals_options_for_select([User.find(1)] + assignable_users, issue.author),
512+
author_options_for_select(issue, issue.project))
513+
end
514+
515+
def test_author_options_for_select_if_persisted_record_and_author_is_anonymous
516+
User.current = User.find(2)
517+
issue = Issue.find(1)
518+
issue.update(author_id: User.anonymous.id)
519+
assignable_users = [User.find(3), User.find(2)]
520+
521+
assert_not_includes assignable_users, issue.author
522+
assert_equal(
523+
principals_options_for_select([User.anonymous] + assignable_users, issue.author),
524+
author_options_for_select(issue, issue.project))
525+
end
468526
end

test/helpers/journals_helper_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
class JournalsHelperTest < Redmine::HelperTest
2323
include JournalsHelper
2424

25-
fixtures :projects, :trackers, :issue_statuses, :issues, :journals,
25+
fixtures :projects, :trackers, :issue_statuses, :issues, :journals, :journal_details,
2626
:enumerations, :issue_categories,
2727
:projects_trackers,
2828
:users, :roles, :member_roles, :members,

test/object_helpers.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def Issue.generate(attributes={})
9595
issue.project ||= Project.find(1)
9696
issue.tracker ||= issue.project.trackers.first
9797
issue.subject = 'Generated' if issue.subject.blank?
98-
issue.author ||= User.find(2)
98+
issue.author ||= (User.current || User.find(2))
9999
yield issue if block_given?
100100
issue
101101
end

0 commit comments

Comments
 (0)