comparison app/models/project.rb @ 1517:dffacf8a6908 redmine-2.5

Update to Redmine SVN revision 13367 on 2.5-stable branch
author Chris Cannam
date Tue, 09 Sep 2014 09:29:00 +0100
parents e248c7af89ec
children a1bdbf8a87d5
comparison
equal deleted inserted replaced
1516:b450a9d58aed 1517:dffacf8a6908
37 has_many :enabled_modules, :dependent => :delete_all 37 has_many :enabled_modules, :dependent => :delete_all
38 has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" 38 has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
39 has_many :issues, :dependent => :destroy, :include => [:status, :tracker] 39 has_many :issues, :dependent => :destroy, :include => [:status, :tracker]
40 has_many :issue_changes, :through => :issues, :source => :journals 40 has_many :issue_changes, :through => :issues, :source => :journals
41 has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC" 41 has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC"
42 has_many :time_entries, :dependent => :delete_all 42 has_many :time_entries, :dependent => :destroy
43 has_many :queries, :class_name => 'IssueQuery', :dependent => :delete_all 43 has_many :queries, :class_name => 'IssueQuery', :dependent => :delete_all
44 has_many :documents, :dependent => :destroy 44 has_many :documents, :dependent => :destroy
45 has_many :news, :dependent => :destroy, :include => :author 45 has_many :news, :dependent => :destroy, :include => :author
46 has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name" 46 has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name"
47 has_many :boards, :dependent => :destroy, :order => "position ASC" 47 has_many :boards, :dependent => :destroy, :order => "position ASC"
54 :class_name => 'IssueCustomField', 54 :class_name => 'IssueCustomField',
55 :order => "#{CustomField.table_name}.position", 55 :order => "#{CustomField.table_name}.position",
56 :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", 56 :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
57 :association_foreign_key => 'custom_field_id' 57 :association_foreign_key => 'custom_field_id'
58 58
59 acts_as_nested_set :order => 'name', :dependent => :destroy 59 acts_as_nested_set :dependent => :destroy
60 acts_as_attachable :view_permission => :view_files, 60 acts_as_attachable :view_permission => :view_files,
61 :delete_permission => :manage_files 61 :delete_permission => :manage_files
62 62
63 acts_as_customizable 63 acts_as_customizable
64 acts_as_searchable :columns => ['name', 'identifier', 'description'], :project_key => 'id', :permission => nil 64 acts_as_searchable :columns => ['name', 'identifier', 'description'], :project_key => 'id', :permission => nil
247 # 247 #
248 # This will raise a ActiveRecord::Rollback if the TimeEntryActivity 248 # This will raise a ActiveRecord::Rollback if the TimeEntryActivity
249 # does not successfully save. 249 # does not successfully save.
250 def create_time_entry_activity_if_needed(activity) 250 def create_time_entry_activity_if_needed(activity)
251 if activity['parent_id'] 251 if activity['parent_id']
252
253 parent_activity = TimeEntryActivity.find(activity['parent_id']) 252 parent_activity = TimeEntryActivity.find(activity['parent_id'])
254 activity['name'] = parent_activity.name 253 activity['name'] = parent_activity.name
255 activity['position'] = parent_activity.position 254 activity['position'] = parent_activity.position
256
257 if Enumeration.overridding_change?(activity, parent_activity) 255 if Enumeration.overridding_change?(activity, parent_activity)
258 project_activity = self.time_entry_activities.create(activity) 256 project_activity = self.time_entry_activities.create(activity)
259
260 if project_activity.new_record? 257 if project_activity.new_record?
261 raise ActiveRecord::Rollback, "Overridding TimeEntryActivity was not successfully saved" 258 raise ActiveRecord::Rollback, "Overridding TimeEntryActivity was not successfully saved"
262 else 259 else
263 self.time_entries.update_all("activity_id = #{project_activity.id}", ["activity_id = ?", parent_activity.id]) 260 self.time_entries.
261 where(["activity_id = ?", parent_activity.id]).
262 update_all("activity_id = #{project_activity.id}")
264 end 263 end
265 end 264 end
266 end 265 end
267 end 266 end
268 267
420 # Used in BuildProjectsTree migration 419 # Used in BuildProjectsTree migration
421 def self.rebuild_tree! 420 def self.rebuild_tree!
422 transaction do 421 transaction do
423 update_all "lft = NULL, rgt = NULL" 422 update_all "lft = NULL, rgt = NULL"
424 rebuild!(false) 423 rebuild!(false)
424 all.each { |p| p.set_or_update_position_under(p.parent) }
425 end 425 end
426 end 426 end
427 427
428 # Returns an array of the trackers used by the project and its active sub projects 428 # Returns an array of the trackers used by the project and its active sub projects
429 def rolled_up_trackers 429 def rolled_up_trackers
438 end 438 end
439 439
440 # Closes open and locked project versions that are completed 440 # Closes open and locked project versions that are completed
441 def close_completed_versions 441 def close_completed_versions
442 Version.transaction do 442 Version.transaction do
443 versions.where(:status => %w(open locked)).all.each do |version| 443 versions.where(:status => %w(open locked)).each do |version|
444 if version.completed? 444 if version.completed?
445 version.update_attribute(:status, 'closed') 445 version.update_attribute(:status, 'closed')
446 end 446 end
447 end 447 end
448 end 448 end
478 end 478 end
479 end 479 end
480 480
481 # Returns a hash of project users grouped by role 481 # Returns a hash of project users grouped by role
482 def users_by_role 482 def users_by_role
483 members.includes(:user, :roles).all.inject({}) do |h, m| 483 members.includes(:user, :roles).inject({}) do |h, m|
484 m.roles.each do |r| 484 m.roles.each do |r|
485 h[r] ||= [] 485 h[r] ||= []
486 h[r] << m.user 486 h[r] << m.user
487 end 487 end
488 h 488 h
620 else 620 else
621 allowed_permissions.include? action 621 allowed_permissions.include? action
622 end 622 end
623 end 623 end
624 624
625 def module_enabled?(module_name) 625 # Return the enabled module with the given name
626 module_name = module_name.to_s 626 # or nil if the module is not enabled for the project
627 enabled_modules.detect {|m| m.name == module_name} 627 def enabled_module(name)
628 name = name.to_s
629 enabled_modules.detect {|m| m.name == name}
630 end
631
632 # Return true if the module with the given name is enabled
633 def module_enabled?(name)
634 enabled_module(name).present?
628 end 635 end
629 636
630 def enabled_module_names=(module_names) 637 def enabled_module_names=(module_names)
631 if module_names && module_names.is_a?(Array) 638 if module_names && module_names.is_a?(Array)
632 module_names = module_names.collect(&:to_s).reject(&:blank?) 639 module_names = module_names.collect(&:to_s).reject(&:blank?)
849 version.update_attribute :status, 'open' 856 version.update_attribute :status, 'open'
850 end 857 end
851 858
852 # Get issues sorted by root_id, lft so that parent issues 859 # Get issues sorted by root_id, lft so that parent issues
853 # get copied before their children 860 # get copied before their children
854 project.issues.reorder('root_id, lft').all.each do |issue| 861 project.issues.reorder('root_id, lft').each do |issue|
855 new_issue = Issue.new 862 new_issue = Issue.new
856 new_issue.copy_from(issue, :subtasks => false, :link => false) 863 new_issue.copy_from(issue, :subtasks => false, :link => false)
857 new_issue.project = self 864 new_issue.project = self
858 # Changing project resets the custom field values 865 # Changing project resets the custom field values
859 # TODO: handle this in Issue#project= 866 # TODO: handle this in Issue#project=
993 end 1000 end
994 end 1001 end
995 1002
996 # Returns the systemwide active activities merged with the project specific overrides 1003 # Returns the systemwide active activities merged with the project specific overrides
997 def system_activities_and_project_overrides(include_inactive=false) 1004 def system_activities_and_project_overrides(include_inactive=false)
998 if include_inactive 1005 t = TimeEntryActivity.table_name
999 return TimeEntryActivity.shared. 1006 scope = TimeEntryActivity.where(
1000 where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all + 1007 "(#{t}.project_id IS NULL AND #{t}.id NOT IN (?)) OR (#{t}.project_id = ?)",
1001 self.time_entry_activities 1008 time_entry_activities.map(&:parent_id), id
1002 else 1009 )
1003 return TimeEntryActivity.shared.active. 1010 unless include_inactive
1004 where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all + 1011 scope = scope.active
1005 self.time_entry_activities.active 1012 end
1006 end 1013 scope
1007 end 1014 end
1008 1015
1009 # Archives subprojects recursively 1016 # Archives subprojects recursively
1010 def archive! 1017 def archive!
1011 children.each do |subproject| 1018 children.each do |subproject|
1015 end 1022 end
1016 1023
1017 def update_position_under_parent 1024 def update_position_under_parent
1018 set_or_update_position_under(parent) 1025 set_or_update_position_under(parent)
1019 end 1026 end
1027
1028 public
1020 1029
1021 # Inserts/moves the project so that target's children or root projects stay alphabetically sorted 1030 # Inserts/moves the project so that target's children or root projects stay alphabetically sorted
1022 def set_or_update_position_under(target_parent) 1031 def set_or_update_position_under(target_parent)
1023 parent_was = parent 1032 parent_was = parent
1024 sibs = (target_parent.nil? ? self.class.roots : target_parent.children) 1033 sibs = (target_parent.nil? ? self.class.roots : target_parent.children)