OSDN Git Service

add Redmine trunk rev 3089
[redminele/redminele.git] / redmine / app / models / enumeration.rb
1 # redMine - project management software
2 # Copyright (C) 2006  Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17
18 class Enumeration < ActiveRecord::Base
19   default_scope :order => "#{Enumeration.table_name}.position ASC"
20   
21   belongs_to :project
22   
23   acts_as_list :scope => 'type = \'#{type}\''
24   acts_as_customizable
25   acts_as_tree :order => 'position ASC'
26
27   before_destroy :check_integrity
28   
29   validates_presence_of :name
30   validates_uniqueness_of :name, :scope => [:type, :project_id]
31   validates_length_of :name, :maximum => 30
32   
33   # Backwards compatiblity named_scopes.
34   # Can be removed post-0.9
35   named_scope :priorities, :conditions => { :type => "IssuePriority" }, :order => 'position' do
36     ActiveSupport::Deprecation.warn("Enumeration#priorities is deprecated, use the IssuePriority class. (#{Redmine::Info.issue(3007)})")
37     def default
38       find(:first, :conditions => { :is_default => true })
39     end
40   end
41
42   named_scope :document_categories, :conditions => { :type => "DocumentCategory" }, :order => 'position' do
43     ActiveSupport::Deprecation.warn("Enumeration#document_categories is deprecated, use the DocumentCategories class. (#{Redmine::Info.issue(3007)})")
44     def default
45       find(:first, :conditions => { :is_default => true })
46     end
47   end
48
49   named_scope :activities, :conditions => { :type => "TimeEntryActivity" }, :order => 'position' do
50     ActiveSupport::Deprecation.warn("Enumeration#activities is deprecated, use the TimeEntryActivity class. (#{Redmine::Info.issue(3007)})")
51     def default
52       find(:first, :conditions => { :is_default => true })
53     end
54   end
55   
56   named_scope :values, lambda {|type| { :conditions => { :type => type }, :order => 'position' } } do
57     def default
58       find(:first, :conditions => { :is_default => true })
59     end
60   end
61   # End backwards compatiblity named_scopes
62
63   named_scope :shared, :conditions => { :project_id => nil }
64   named_scope :active, :conditions => { :active => true }
65
66   def self.default
67     # Creates a fake default scope so Enumeration.default will check
68     # it's type.  STI subclasses will automatically add their own
69     # types to the finder.
70     if self.descends_from_active_record?
71       find(:first, :conditions => { :is_default => true, :type => 'Enumeration' })
72     else
73       # STI classes are
74       find(:first, :conditions => { :is_default => true })
75     end
76   end
77   
78   # Overloaded on concrete classes
79   def option_name
80     nil
81   end
82
83   # Backwards compatiblity.  Can be removed post-0.9
84   def opt
85     ActiveSupport::Deprecation.warn("Enumeration#opt is deprecated, use the STI classes now. (#{Redmine::Info.issue(3007)})")
86     return OptName
87   end
88
89   def before_save
90     if is_default? && is_default_changed?
91       Enumeration.update_all("is_default = #{connection.quoted_false}", {:type => type})
92     end
93   end
94   
95   # Overloaded on concrete classes
96   def objects_count
97     0
98   end
99   
100   def in_use?
101     self.objects_count != 0
102   end
103
104   # Is this enumeration overiding a system level enumeration?
105   def is_override?
106     !self.parent.nil?
107   end
108   
109   alias :destroy_without_reassign :destroy
110   
111   # Destroy the enumeration
112   # If a enumeration is specified, objects are reassigned
113   def destroy(reassign_to = nil)
114     if reassign_to && reassign_to.is_a?(Enumeration)
115       self.transfer_relations(reassign_to)
116     end
117     destroy_without_reassign
118   end
119   
120   def <=>(enumeration)
121     position <=> enumeration.position
122   end
123   
124   def to_s; name end
125
126   # Returns the Subclasses of Enumeration.  Each Subclass needs to be
127   # required in development mode.
128   #
129   # Note: subclasses is protected in ActiveRecord
130   def self.get_subclasses
131     @@subclasses[Enumeration]
132   end
133
134   # Does the +new+ Hash override the previous Enumeration?
135   def self.overridding_change?(new, previous)
136     if (same_active_state?(new['active'], previous.active)) && same_custom_values?(new,previous)
137       return false
138     else
139       return true
140     end
141   end
142
143   # Does the +new+ Hash have the same custom values as the previous Enumeration?
144   def self.same_custom_values?(new, previous)
145     previous.custom_field_values.each do |custom_value|
146       if custom_value.value != new["custom_field_values"][custom_value.custom_field_id.to_s]
147         return false
148       end
149     end
150
151     return true
152   end
153   
154   # Are the new and previous fields equal?
155   def self.same_active_state?(new, previous)
156     new = (new == "1" ? true : false)
157     return new == previous
158   end
159   
160 private
161   def check_integrity
162     raise "Can't delete enumeration" if self.in_use?
163   end
164
165 end
166
167 # Force load the subclasses in development mode
168 require_dependency 'time_entry_activity'
169 require_dependency 'document_category'
170 require_dependency 'issue_priority'