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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2019 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. class Enumeration < ActiveRecord::Base
  19. include Redmine::SubclassFactory
  20. default_scope lambda {order(:position)}
  21. belongs_to :project
  22. acts_as_positioned :scope => :parent_id
  23. acts_as_customizable
  24. acts_as_tree
  25. before_destroy :check_integrity
  26. before_save :check_default
  27. validates_presence_of :name
  28. validates_uniqueness_of :name, :scope => [:type, :project_id]
  29. validates_length_of :name, :maximum => 30
  30. scope :shared, lambda { where(:project_id => nil) }
  31. scope :sorted, lambda { order(:position) }
  32. scope :active, lambda { where(:active => true) }
  33. scope :system, lambda { where(:project_id => nil) }
  34. scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
  35. def self.default
  36. # Creates a fake default scope so Enumeration.default will check
  37. # it's type. STI subclasses will automatically add their own
  38. # types to the finder.
  39. if self.descends_from_active_record?
  40. where(:is_default => true, :type => 'Enumeration').first
  41. else
  42. # STI classes are
  43. where(:is_default => true).first
  44. end
  45. end
  46. # Overloaded on concrete classes
  47. def option_name
  48. nil
  49. end
  50. def check_default
  51. if is_default? && is_default_changed?
  52. Enumeration.where({:type => type}).update_all({:is_default => false})
  53. end
  54. end
  55. # Overloaded on concrete classes
  56. def objects_count
  57. 0
  58. end
  59. def in_use?
  60. self.objects_count != 0
  61. end
  62. # Is this enumeration overriding a system level enumeration?
  63. def is_override?
  64. !self.parent.nil?
  65. end
  66. alias :destroy_without_reassign :destroy
  67. # Destroy the enumeration
  68. # If a enumeration is specified, objects are reassigned
  69. def destroy(reassign_to = nil)
  70. if reassign_to && reassign_to.is_a?(Enumeration)
  71. self.transfer_relations(reassign_to)
  72. end
  73. destroy_without_reassign
  74. end
  75. def <=>(enumeration)
  76. position <=> enumeration.position
  77. end
  78. def to_s; name end
  79. # Returns the Subclasses of Enumeration. Each Subclass needs to be
  80. # required in development mode.
  81. #
  82. # Note: subclasses is protected in ActiveRecord
  83. def self.get_subclasses
  84. subclasses
  85. end
  86. # Does the +new+ Hash override the previous Enumeration?
  87. def self.overriding_change?(new, previous)
  88. if (same_active_state?(new['active'], previous.active)) && same_custom_values?(new,previous)
  89. return false
  90. else
  91. return true
  92. end
  93. end
  94. # Does the +new+ Hash have the same custom values as the previous Enumeration?
  95. def self.same_custom_values?(new, previous)
  96. previous.custom_field_values.each do |custom_value|
  97. if custom_value.value != new["custom_field_values"][custom_value.custom_field_id.to_s]
  98. return false
  99. end
  100. end
  101. return true
  102. end
  103. # Are the new and previous fields equal?
  104. def self.same_active_state?(new, previous)
  105. new = (new == "1" ? true : false)
  106. return new == previous
  107. end
  108. private
  109. def check_integrity
  110. raise "Cannot delete enumeration" if self.in_use?
  111. end
  112. # Overrides Redmine::Acts::Positioned#set_default_position so that enumeration overrides
  113. # get the same position as the overridden enumeration
  114. def set_default_position
  115. if position.nil? && parent
  116. self.position = parent.position
  117. end
  118. super
  119. end
  120. # Overrides Redmine::Acts::Positioned#update_position so that overrides get the same
  121. # position as the overridden enumeration
  122. def update_position
  123. super
  124. if saved_change_to_position?
  125. self.class.where.not(:parent_id => nil).update_all(
  126. "position = coalesce((
  127. select position
  128. from (select id, position from enumerations) as parent
  129. where parent_id = parent.id), 1)"
  130. )
  131. end
  132. end
  133. # Overrides Redmine::Acts::Positioned#remove_position so that enumeration overrides
  134. # get the same position as the overridden enumeration
  135. def remove_position
  136. if parent_id.blank?
  137. super
  138. end
  139. end
  140. end
  141. # Force load the subclasses in development mode
  142. require_dependency 'time_entry_activity'
  143. require_dependency 'document_category'
  144. require_dependency 'issue_priority'