You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

enumeration.rb 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. # Redmine - project management software
  2. # Copyright (C) 2006-2017 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. class Enumeration < ActiveRecord::Base
  18. include Redmine::SubclassFactory
  19. default_scope lambda {order(:position)}
  20. belongs_to :project
  21. acts_as_positioned :scope => :parent_id
  22. acts_as_customizable
  23. acts_as_tree
  24. before_destroy :check_integrity
  25. before_save :check_default
  26. validates_presence_of :name
  27. validates_uniqueness_of :name, :scope => [:type, :project_id]
  28. validates_length_of :name, :maximum => 30
  29. scope :shared, lambda { where(:project_id => nil) }
  30. scope :sorted, lambda { order(:position) }
  31. scope :active, lambda { where(:active => true) }
  32. scope :system, lambda { where(:project_id => nil) }
  33. scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
  34. def self.default
  35. # Creates a fake default scope so Enumeration.default will check
  36. # it's type. STI subclasses will automatically add their own
  37. # types to the finder.
  38. if self.descends_from_active_record?
  39. where(:is_default => true, :type => 'Enumeration').first
  40. else
  41. # STI classes are
  42. where(:is_default => true).first
  43. end
  44. end
  45. # Overloaded on concrete classes
  46. def option_name
  47. nil
  48. end
  49. def check_default
  50. if is_default? && is_default_changed?
  51. Enumeration.where({:type => type}).update_all({:is_default => false})
  52. end
  53. end
  54. # Overloaded on concrete classes
  55. def objects_count
  56. 0
  57. end
  58. def in_use?
  59. self.objects_count != 0
  60. end
  61. # Is this enumeration overriding a system level enumeration?
  62. def is_override?
  63. !self.parent.nil?
  64. end
  65. alias :destroy_without_reassign :destroy
  66. # Destroy the enumeration
  67. # If a enumeration is specified, objects are reassigned
  68. def destroy(reassign_to = nil)
  69. if reassign_to && reassign_to.is_a?(Enumeration)
  70. self.transfer_relations(reassign_to)
  71. end
  72. destroy_without_reassign
  73. end
  74. def <=>(enumeration)
  75. position <=> enumeration.position
  76. end
  77. def to_s; name end
  78. # Returns the Subclasses of Enumeration. Each Subclass needs to be
  79. # required in development mode.
  80. #
  81. # Note: subclasses is protected in ActiveRecord
  82. def self.get_subclasses
  83. subclasses
  84. end
  85. # Does the +new+ Hash override the previous Enumeration?
  86. def self.overriding_change?(new, previous)
  87. if (same_active_state?(new['active'], previous.active)) && same_custom_values?(new,previous)
  88. return false
  89. else
  90. return true
  91. end
  92. end
  93. # Does the +new+ Hash have the same custom values as the previous Enumeration?
  94. def self.same_custom_values?(new, previous)
  95. previous.custom_field_values.each do |custom_value|
  96. if custom_value.value != new["custom_field_values"][custom_value.custom_field_id.to_s]
  97. return false
  98. end
  99. end
  100. return true
  101. end
  102. # Are the new and previous fields equal?
  103. def self.same_active_state?(new, previous)
  104. new = (new == "1" ? true : false)
  105. return new == previous
  106. end
  107. private
  108. def check_integrity
  109. raise "Cannot delete enumeration" if self.in_use?
  110. end
  111. # Overrides Redmine::Acts::Positioned#set_default_position so that enumeration overrides
  112. # get the same position as the overridden enumeration
  113. def set_default_position
  114. if position.nil? && parent
  115. self.position = parent.position
  116. end
  117. super
  118. end
  119. # Overrides Redmine::Acts::Positioned#update_position so that overrides get the same
  120. # position as the overridden enumeration
  121. def update_position
  122. super
  123. if saved_change_to_position?
  124. self.class.where.not(:parent_id => nil).update_all(
  125. "position = coalesce((
  126. select position
  127. from (select id, position from enumerations) as parent
  128. where parent_id = parent.id), 1)"
  129. )
  130. end
  131. end
  132. # Overrides Redmine::Acts::Positioned#remove_position so that enumeration overrides
  133. # get the same position as the overridden enumeration
  134. def remove_position
  135. if parent_id.blank?
  136. super
  137. end
  138. end
  139. end
  140. # Force load the subclasses in development mode
  141. require_dependency 'time_entry_activity'
  142. require_dependency 'document_category'
  143. require_dependency 'issue_priority'