diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2014-11-02 19:45:14 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2014-11-02 19:45:14 +0000 |
commit | dfc594c33702a123674dcae1d6b4bfe3a2f32fd3 (patch) | |
tree | 42f8653451b35f54db68bf914e1d963bfaf13418 /app/models | |
parent | 32b79b6fd4e3a523ee393d7a3e2bb60dbeed77c3 (diff) | |
download | redmine-dfc594c33702a123674dcae1d6b4bfe3a2f32fd3.tar.gz redmine-dfc594c33702a123674dcae1d6b4bfe3a2f32fd3.zip |
Default status per tracker (#5991).
git-svn-id: http://svn.redmine.org/redmine/trunk@13535 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/issue.rb | 61 | ||||
-rw-r--r-- | app/models/issue_status.rb | 16 | ||||
-rw-r--r-- | app/models/tracker.rb | 17 |
3 files changed, 67 insertions, 27 deletions
diff --git a/app/models/issue.rb b/app/models/issue.rb index 144dffa9f..492e98687 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -162,7 +162,6 @@ class Issue < ActiveRecord::Base super if new_record? # set default values for new records only - self.status ||= IssueStatus.default self.priority ||= IssuePriority.default self.watcher_user_ids = [] end @@ -273,11 +272,19 @@ class Issue < ActiveRecord::Base issue.save ? issue : false end - def status_id=(sid) - self.status = nil - result = write_attribute(:status_id, sid) - @workflow_rule_by_attribute = nil - result + def status_id=(status_id) + if status_id.to_s != self.status_id.to_s + self.status = (status_id.present? ? IssueStatus.find_by_id(status_id) : nil) + end + self.status_id + end + + # Sets the status. + def self.status=(status) + if status != self.status + @workflow_rule_by_attribute = nil + end + association(:status).writer(status) end def priority_id=(pid) @@ -302,12 +309,24 @@ class Issue < ActiveRecord::Base self.tracker_id end + # Sets the tracker. + # This will set the status to the default status of the new tracker if: + # * the status was the default for the previous tracker + # * or if the status was not part of the new tracker statuses + # * or the status was nil def tracker=(tracker) if tracker != self.tracker + if status == default_status + self.status = nil + elsif status && tracker && !tracker.issue_status_ids.include?(status.id) + self.status = nil + end @custom_field_values = nil @workflow_rule_by_attribute = nil end association(:tracker).writer(tracker) + self.status ||= default_status + self.tracker end def project_id=(project_id) @@ -317,6 +336,14 @@ class Issue < ActiveRecord::Base self.project_id end + # Sets the project. + # Unless keep_tracker argument is set to true, this will change the tracker + # to the first tracker of the new project if the previous tracker is not part + # of the new project trackers. + # This will clear the fixed_version is it's no longer valid for the new project. + # This will clear the parent issue if it's no longer valid for the new project. + # This will set the category to the category with the same name in the new + # project if it exists, or clear it if it doesn't. def project=(project, keep_tracker=false) project_was = self.project association(:project).writer(project) @@ -339,7 +366,9 @@ class Issue < ActiveRecord::Base self.parent_issue_id = nil end @custom_field_values = nil + @workflow_rule_by_attribute = nil end + self.project end def description=(arg) @@ -776,14 +805,28 @@ class Issue < ActiveRecord::Base !relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil? end + # Returns the default status of the issue based on its tracker + # Returns nil if tracker is nil + def default_status + tracker.try(:default_status) + end + # Returns an array of statuses that user is able to apply def new_statuses_allowed_to(user=User.current, include_default=false) if new_record? && @copied_from - [IssueStatus.default, @copied_from.status].compact.uniq.sort + [default_status, @copied_from.status].compact.uniq.sort else initial_status = nil if new_record? - initial_status = IssueStatus.default + initial_status = default_status + elsif tracker_id_changed? + if Tracker.where(:id => tracker_id_was, :default_status_id => status_id_was).any? + initial_status = default_status + elsif tracker.issue_status_ids.include?(status_id_was) + initial_status = IssueStatus.find_by_id(status_id_was) + else + initial_status = default_status + end else initial_status = status_was end @@ -802,7 +845,7 @@ class Issue < ActiveRecord::Base ) end statuses << initial_status unless statuses.empty? - statuses << IssueStatus.default if include_default + statuses << default_status if include_default statuses = statuses.compact.uniq.sort if blocked? statuses.reject!(&:is_closed?) diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb index 76c5ef65b..b8eb6d40e 100644 --- a/app/models/issue_status.rb +++ b/app/models/issue_status.rb @@ -22,7 +22,6 @@ class IssueStatus < ActiveRecord::Base acts_as_list before_destroy :delete_workflow_rules - after_save :update_default validates_presence_of :name validates_uniqueness_of :name @@ -33,15 +32,6 @@ class IssueStatus < ActiveRecord::Base scope :sorted, lambda { order(:position) } scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} - def update_default - IssueStatus.where(['id <> ?', id]).update_all({:is_default => false}) if self.is_default? - end - - # Returns the default status for new issues - def self.default - where(:is_default => true).first - end - # Update all the +Issues+ setting their done_ratio to the value of their +IssueStatus+ def self.update_issue_done_ratios if Issue.use_status_for_done_ratio? @@ -100,7 +90,11 @@ class IssueStatus < ActiveRecord::Base private def check_integrity - raise "Can't delete status" if Issue.where(:status_id => id).any? + if Issue.where(:status_id => id).any? + raise "This status is used by some issues" + elsif Tracker.where(:default_status_id => id).any? + raise "This status is used as the default status by some trackers" + end end # Deletes associated workflows diff --git a/app/models/tracker.rb b/app/models/tracker.rb index 1c867c5f1..4b86a7ecb 100644 --- a/app/models/tracker.rb +++ b/app/models/tracker.rb @@ -24,6 +24,7 @@ class Tracker < ActiveRecord::Base CORE_FIELDS_ALL = (CORE_FIELDS_UNDISABLABLE + CORE_FIELDS).freeze before_destroy :check_integrity + belongs_to :default_status, :class_name => 'IssueStatus' has_many :issues has_many :workflow_rules, :dependent => :delete_all do def copy(source_tracker) @@ -37,6 +38,7 @@ class Tracker < ActiveRecord::Base attr_protected :fields_bits + validates_presence_of :default_status validates_presence_of :name validates_uniqueness_of :name validates_length_of :name, :maximum => 30 @@ -53,14 +55,15 @@ class Tracker < ActiveRecord::Base # Returns an array of IssueStatus that are used # in the tracker's workflows def issue_statuses - if @issue_statuses - return @issue_statuses - elsif new_record? - return [] - end + @issue_statuses ||= IssueStatus.where(:id => issue_status_ids).to_a.sort + end - status_ids = WorkflowTransition.where(:tracker_id => id).uniq.pluck(:old_status_id, :new_status_id).flatten.uniq - @issue_statuses = IssueStatus.where(:id => status_ids).to_a.sort + def issue_status_ids + if new_record? + [] + else + @issue_status_ids ||= WorkflowTransition.where(:tracker_id => id).uniq.pluck(:old_status_id, :new_status_id).flatten.uniq + end end def disabled_core_fields |