From: Jean-Philippe Lang Date: Mon, 30 May 2016 18:20:13 +0000 (+0000) Subject: Adds Issue#allowed_target_trackers (#7839). X-Git-Tag: 3.4.0~954 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a6828512c02b20eaeb9c42fc2612c7010ede73fa;p=redmine.git Adds Issue#allowed_target_trackers (#7839). git-svn-id: http://svn.redmine.org/redmine/trunk@15430 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- diff --git a/app/controllers/context_menus_controller.rb b/app/controllers/context_menus_controller.rb index 1e5652d09..59ee3a77a 100644 --- a/app/controllers/context_menus_controller.rb +++ b/app/controllers/context_menus_controller.rb @@ -41,12 +41,11 @@ class ContextMenusController < ApplicationController else @assignables = @project.assignable_users end - @trackers = @project.trackers else #when multiple projects, we only keep the intersection of each set @assignables = @projects.map(&:assignable_users).reduce(:&) - @trackers = @projects.map(&:trackers).reduce(:&) end + @trackers = @projects.map {|p| Issue.allowed_target_trackers(p) }.reduce(:&) @versions = @projects.map {|p| p.shared_versions.open}.reduce(:&) @priorities = IssuePriority.active.reverse diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index cf402de22..1db5e6ff8 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -230,7 +230,7 @@ class IssuesController < ApplicationController end @custom_fields = @issues.map{|i|i.editable_custom_fields}.reduce(:&) @assignables = target_projects.map(&:assignable_users).reduce(:&) - @trackers = target_projects.map(&:trackers).reduce(:&) + @trackers = target_projects.map {|p| Issue.allowed_target_trackers(p) }.reduce(:&) @versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&) @categories = target_projects.map {|p| p.issue_categories}.reduce(:&) if @copy @@ -465,7 +465,7 @@ class IssuesController < ApplicationController @issue.safe_attributes = attrs if @issue.project - @issue.tracker ||= @issue.project.trackers.first + @issue.tracker ||= @issue.allowed_target_trackers.first if @issue.tracker.nil? render_error l(:error_no_tracker_in_project) return false diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index b505765d8..ce6d9f8f2 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -168,6 +168,16 @@ module IssuesHelper link_to(l(:button_add), new_project_issue_path(issue.project, :issue => attrs)) end + def trackers_options_for_select(issue) + trackers = issue.allowed_target_trackers + if issue.new_record? && issue.parent_issue_id.present? + trackers = trackers.reject do |tracker| + issue.tracker_id != tracker.id && tracker.disabled_core_fields.include?('parent_issue_id') + end + end + trackers.collect {|t| [t.name, t.id]} + end + class IssueFieldsRows include ActionView::Helpers::TagHelper diff --git a/app/models/issue.rb b/app/models/issue.rb index 0ee8ff3d3..d6133d3a9 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -479,12 +479,14 @@ class Issue < ActiveRecord::Base end if (t = attrs.delete('tracker_id')) && safe_attribute?('tracker_id') - self.tracker_id = t + if allowed_target_trackers(user).where(:id => t.to_i).exists? + self.tracker_id = t + end end if project - # Set the default tracker to accept custom field values + # Set a default tracker to accept custom field values # even if tracker is not specified - self.tracker ||= project.trackers.first + self.tracker ||= allowed_target_trackers(user).first end statuses_allowed = new_statuses_allowed_to(user) @@ -822,16 +824,6 @@ class Issue < ActiveRecord::Base !leaf? end - def assignable_trackers - trackers = project.trackers - if new_record? && parent_issue_id.present? - trackers = trackers.reject do |tracker| - tracker_id != tracker.id && tracker.disabled_core_fields.include?('parent_issue_id') - end - end - trackers - end - # Users the issue can be assigned to def assignable_users users = project.assignable_users.to_a @@ -1373,6 +1365,20 @@ class Issue < ActiveRecord::Base end Project.where(condition).having_trackers end + + # Returns a scope of trackers that user can assign the issue to + def allowed_target_trackers(user=User.current) + if project + self.class.allowed_target_trackers(project, user, tracker_id_was) + else + Tracker.none + end + end + + # Returns a scope of trackers that user can assign project issues to + def self.allowed_target_trackers(project, user=User.current, current_tracker=nil) + project.trackers.sorted + end private diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb index 40bd02a07..a619f115d 100644 --- a/app/models/mail_handler.rb +++ b/app/models/mail_handler.rb @@ -199,7 +199,14 @@ class MailHandler < ActionMailer::Base end issue = Issue.new(:author => user, :project => project) - issue.safe_attributes = issue_attributes_from_keywords(issue) + attributes = issue_attributes_from_keywords(issue) + if handler_options[:no_permission_check] + issue.tracker_id = attributes['tracker_id'] + if project + issue.tracker_id ||= project.trackers.first.try(:id) + end + end + issue.safe_attributes = attributes issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)} issue.subject = cleaned_up_subject if issue.subject.blank? @@ -420,10 +427,6 @@ class MailHandler < ActionMailer::Base 'done_ratio' => get_keyword(:done_ratio, :format => '(\d|10)?0') }.delete_if {|k, v| v.blank? } - if issue.new_record? && attrs['tracker_id'].nil? - attrs['tracker_id'] = issue.project.trackers.first.try(:id) - end - attrs end diff --git a/app/views/issues/_form.html.erb b/app/views/issues/_form.html.erb index 788a2f38e..1e82b6f84 100644 --- a/app/views/issues/_form.html.erb +++ b/app/views/issues/_form.html.erb @@ -14,7 +14,7 @@ <% end %> <% if @issue.safe_attribute? 'tracker_id' %> -

<%= f.select :tracker_id, @issue.assignable_trackers.collect {|t| [t.name, t.id]}, {:required => true}, +

<%= f.select :tracker_id, trackers_options_for_select(@issue), {:required => true}, :onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %>

<% end %> diff --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb index 7dcba2629..fd762023f 100644 --- a/app/views/issues/index.html.erb +++ b/app/views/issues/index.html.erb @@ -1,5 +1,5 @@
- <% if User.current.allowed_to?(:add_issues, @project, :global => true) && (@project.nil? || @project.trackers.any?) %> + <% if User.current.allowed_to?(:add_issues, @project, :global => true) && (@project.nil? || Issue.allowed_target_trackers(@project).any?) %> <%= link_to l(:label_issue_new), _new_project_issue_path(@project), :class => 'icon icon-add new-issue' %> <% end %>
diff --git a/lib/redmine.rb b/lib/redmine.rb index 1d37a523b..0c670d1b5 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -233,7 +233,7 @@ Redmine::MenuManager.map :project_menu do |menu| menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural menu.push :new_issue, { :controller => 'issues', :action => 'new', :copy_from => nil }, :param => :project_id, :caption => :label_issue_new, :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }, - :if => Proc.new { |p| Setting.new_project_issue_tab_enabled? && p.trackers.any? }, + :if => Proc.new { |p| Setting.new_project_issue_tab_enabled? && Issue.allowed_target_trackers(p).any? }, :permission => :add_issues menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index d7c7d231b..363cdd071 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -737,9 +737,10 @@ class IssueTest < ActiveSupport::TestCase target = Tracker.find(2) target.core_fields = %w(assigned_to_id due_date) target.save! + user = User.find(2) - issue = Issue.new(:tracker => source) - issue.safe_attributes = {'tracker_id' => 2, 'due_date' => '2012-07-14'} + issue = Issue.new(:project => Project.find(1), :tracker => source) + issue.send :safe_attributes=, {'tracker_id' => 2, 'due_date' => '2012-07-14'}, user assert_equal target, issue.tracker assert_equal Date.parse('2012-07-14'), issue.due_date end