summaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2014-11-02 19:45:14 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2014-11-02 19:45:14 +0000
commitdfc594c33702a123674dcae1d6b4bfe3a2f32fd3 (patch)
tree42f8653451b35f54db68bf914e1d963bfaf13418 /app/models
parent32b79b6fd4e3a523ee393d7a3e2bb60dbeed77c3 (diff)
downloadredmine-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.rb61
-rw-r--r--app/models/issue_status.rb16
-rw-r--r--app/models/tracker.rb17
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