##// END OF EJS Templates
Time entry queries should be copied and deleted too....
Time entry queries should be copied and deleted too. git-svn-id: http://svn.redmine.org/redmine/trunk@16320 e93f8b46-1217-0410-a6f0-8f06a7374b81

File last commit:

r15938:1b911e51f962
r15938:1b911e51f962
Show More
project.rb
1096 lines | 38.2 KiB | text/x-ruby | RubyLexer
Jean-Philippe Lang
Changed the way the visibility SQL statement is built....
r5020 # Redmine - project management software
Jean-Philippe Lang
Updates copyright for 2016....
r14856 # Copyright (C) 2006-2016 Jean-Philippe Lang
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 #
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397 #
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397 #
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Project < ActiveRecord::Base
Jean-Philippe Lang
Declare safe attributes for User and Projects models....
r4378 include Redmine::SafeAttributes
Jean-Philippe Lang
Replaces awesome_nested_set gem with a simple and more robust implementation of nested sets....
r13459 include Redmine::NestedSet::ProjectNestedSet
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Added the ability to archive projects:...
r546 # Project statuses
STATUS_ACTIVE = 1
Jean-Philippe Lang
Ability to close projects (read-only) (#3640)....
r9700 STATUS_CLOSED = 5
Jean-Philippe Lang
Added the ability to archive projects:...
r546 STATUS_ARCHIVED = 9
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Raised maximum length of project names and identifiers to 255 and 100 respectively (#6446)....
r4288 # Maximum length for project identifiers
IDENTIFIER_MAX_LENGTH = 100
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Toshi MARUYAMA
fix typos of source comments at Project model...
r12800 # Specific overridden Activities
Jean-Philippe Lang
Changes misleading scopes on Enumeration....
r2969 has_many :time_entry_activities
Jean-Philippe Lang
Deprecates Project#member_principals....
r13950 has_many :memberships, :class_name => 'Member', :inverse_of => :project
# Memberships of active users only
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 has_many :members,
Jean-Philippe Lang
Deprecates Project#member_principals....
r13950 lambda { joins(:principal).where(:users => {:type => 'User', :status => Principal::STATUS_ACTIVE}) }
Jean-Philippe Lang
Added project module concept....
r714 has_many :enabled_modules, :dependent => :delete_all
Jean-Philippe Lang
Fixed SQL errors with SQLServer (column specified more than once in the order by list) after r13526....
r13145 has_and_belongs_to_many :trackers, lambda {order(:position)}
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 has_many :issues, :dependent => :destroy
Jean-Philippe Lang
Activity view improvements:...
r640 has_many :issue_changes, :through => :issues, :source => :journals
Jean-Philippe Lang
Removes default order on Project#versions association....
r15937 has_many :versions, :dependent => :destroy
Jean-Philippe Lang
Default target version for new issues (#1828)....
r14404 belongs_to :default_version, :class_name => 'Version'
Jean-Philippe Lang
Fixed that time entries custom values are not deleted when deleting a project or an issue (#15709)....
r12146 has_many :time_entries, :dependent => :destroy
Jean-Philippe Lang
Time entry queries should be copied and deleted too....
r15938 has_many :queries, :dependent => :delete_all
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 has_many :documents, :dependent => :destroy
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 has_many :news, lambda {includes(:author)}, :dependent => :destroy
has_many :issue_categories, lambda {order("#{IssueCategory.table_name}.name")}, :dependent => :delete_all
has_many :boards, lambda {order("position ASC")}, :dependent => :destroy
has_one :repository, lambda {where(["is_default = ?", true])}
Jean-Philippe Lang
Adds support for multiple repositories per project (#779)....
r8530 has_many :repositories, :dependent => :destroy
Jean-Philippe Lang
Improved Redmine links:...
r703 has_many :changesets, :through => :repository
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 has_one :wiki, :dependent => :destroy
Jean-Philippe Lang
Custom fields can now be reordered....
r888 # Custom field for the project issues
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397 has_and_belongs_to_many :issue_custom_fields,
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 lambda {order("#{CustomField.table_name}.position")},
Jean-Philippe Lang
Custom fields can now be reordered....
r888 :class_name => 'IssueCustomField',
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
:association_foreign_key => 'custom_field_id'
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Files module: makes version field non required (#1053)....
r2115 acts_as_attachable :view_permission => :view_files,
Jean-Philippe Lang
Edit attachments after upload (#1326)....
r13283 :edit_permission => :manage_files,
Jean-Philippe Lang
Files module: makes version field non required (#1053)....
r2115 :delete_permission => :manage_files
Jean-Philippe Lang
Search engines now supports pagination....
r755
Jean-Philippe Lang
Custom fields refactoring: most of code moved from controllers to models (using new module ActsAsCustomizable)....
r1578 acts_as_customizable
Jean-Philippe Lang
Option to search attachment filenames and description (#4383)....
r13474 acts_as_searchable :columns => ['name', 'identifier', 'description'], :project_key => "#{Project.table_name}.id", :permission => nil
Jean-Philippe Lang
Search engines now supports pagination....
r755 acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"},
Jean-Philippe Lang
Fixed: projects are referenced by id in search results....
r3368 :url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o}},
Jean-Philippe Lang
Fixed: no :author method error on projects atom feed (#1623)....
r1639 :author => nil
Jean-Philippe Lang
Search engines now supports pagination....
r755
Jean-Philippe Lang
Moves enabled_module_names param to project attribute so that it can be set through the Project API....
r4525 attr_protected :status
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Unlimited and optional project description. The project list will show truncated descriptions only (the first fews lines)....
r1074 validates_presence_of :name, :identifier
Jean-Philippe Lang
Skip some validations if attribute did not change....
r13341 validates_uniqueness_of :identifier, :if => Proc.new {|p| p.identifier_changed?}
Jean-Philippe Lang
Raised maximum length of project names and identifiers to 255 and 100 respectively (#6446)....
r4288 validates_length_of :name, :maximum => 255
Jean-Philippe Lang
Change projects homepage limit to 255 chars (#663, #1095)....
r1443 validates_length_of :homepage, :maximum => 255
Jean-Philippe Lang
Don't return 2 errors when identifier is blank (blank + too short)....
r15605 validates_length_of :identifier, :maximum => IDENTIFIER_MAX_LENGTH
Toshi MARUYAMA
fix typos of source comments at Project model...
r12800 # downcase letters, digits, dashes but not digits only
Jean-Philippe Lang
Use \A and \z in validation regexps....
r10733 validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? }
Jean-Philippe Lang
Prevent creation of project with identifier 'new' (#3602)....
r2716 # reserved words
validates_exclusion_of :identifier, :in => %w( new )
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 validate :validate_parent
Jean-Philippe Lang
Prevent creation of project with identifier 'new' (#3602)....
r2716
Jean-Philippe Lang
Optionaly inherit members from parent project (#5605)....
r11068 after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?}
Jean-Philippe Lang
Replaces awesome_nested_set gem with a simple and more robust implementation of nested sets....
r13459 after_save :remove_inherited_member_roles, :add_inherited_member_roles, :if => Proc.new {|project| project.parent_id_changed?}
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 after_update :update_versions_from_hierarchy_change, :if => Proc.new {|project| project.parent_id_changed?}
Jean-Philippe Lang
Fixed: children projects are deleted instead of being destroyed when destroying parent project (#7904)....
r5051 before_destroy :delete_all_members
Jean-Philippe Lang
Merged nbc branch @ r1812 (commit access permission and reposman improvements)....
r1812
Jean-Philippe Lang
Rewrites named scopes with ARel queries....
r10723 scope :has_module, lambda {|mod|
where("#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s)
}
scope :active, lambda { where(:status => STATUS_ACTIVE) }
scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
scope :all_public, lambda { where(:is_public => true) }
scope :visible, lambda {|*args| where(Project.visible_condition(args.shift || User.current, *args)) }
Toshi MARUYAMA
remove trailing white-space from app/models/project.rb...
r11506 scope :allowed_to, lambda {|*args|
Jean-Philippe Lang
Enable global time logging at /time_entries/new (#10020)....
r8571 user = User.current
permission = nil
if args.first.is_a?(Symbol)
permission = args.shift
else
user = args.shift
permission = args.shift
end
Jean-Philippe Lang
Rewrites named scopes with ARel queries....
r10723 where(Project.allowed_to_condition(user, permission, *args))
Jean-Philippe Lang
Enable global time logging at /time_entries/new (#10020)....
r8571 }
Toshi MARUYAMA
model: replace Rails2 "named_scope" to Rails3 "scope"...
r9355 scope :like, lambda {|arg|
Jean-Philippe Lang
Adds named scopes for projects index....
r7962 if arg.blank?
Jean-Philippe Lang
Rewrites named scopes with ARel queries....
r10723 where(nil)
Jean-Philippe Lang
Adds named scopes for projects index....
r7962 else
pattern = "%#{arg.to_s.strip.downcase}%"
Jean-Philippe Lang
Rewrites named scopes with ARel queries....
r10723 where("LOWER(identifier) LIKE :p OR LOWER(name) LIKE :p", :p => pattern)
Jean-Philippe Lang
Adds named scopes for projects index....
r7962 end
}
Jean-Philippe Lang
Adds a 'sorted' scope to Project....
r13159 scope :sorted, lambda {order(:lft)}
Jean-Philippe Lang
Don't propose projects without trackers when editing an issue (#20463)....
r14231 scope :having_trackers, lambda {
where("#{Project.table_name}.id IN (SELECT DISTINCT project_id FROM #{table_name_prefix}projects_trackers#{table_name_suffix})")
}
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Makes models #initialize accept additional arguments....
r8167 def initialize(attributes=nil, *args)
Jean-Philippe Lang
Moves project attributes default assignments from ProjectsController#new to the model (#6064)....
r4346 super
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Moves project attributes default assignments from ProjectsController#new to the model (#6064)....
r4346 initialized = (attributes || {}).stringify_keys
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397 if !initialized.key?('identifier') && Setting.sequential_project_identifiers?
Jean-Philippe Lang
Moves project attributes default assignments from ProjectsController#new to the model (#6064)....
r4346 self.identifier = Project.next_identifier
end
if !initialized.key?('is_public')
self.is_public = Setting.default_projects_public?
end
if !initialized.key?('enabled_module_names')
self.enabled_module_names = Setting.default_projects_modules
end
if !initialized.key?('trackers') && !initialized.key?('tracker_ids')
Jean-Philippe Lang
Possibility to define the default enable trackers when creating a project (#13175)....
r11164 default = Setting.default_projects_tracker_ids
if default.is_a?(Array)
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.to_a
Jean-Philippe Lang
Possibility to define the default enable trackers when creating a project (#13175)....
r11164 else
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 self.trackers = Tracker.sorted.to_a
Jean-Philippe Lang
Possibility to define the default enable trackers when creating a project (#13175)....
r11164 end
Jean-Philippe Lang
Moves project attributes default assignments from ProjectsController#new to the model (#6064)....
r4346 end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Initial commit for svn repository management and access control:...
r393 def identifier=(identifier)
super unless identifier_frozen?
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Initial commit for svn repository management and access control:...
r393 def identifier_frozen?
Jean-Philippe Lang
Fixed that project identifier can always be updated (#11028)....
r9527 errors[:identifier].blank? && !(new_record? || identifier.blank?)
Jean-Philippe Lang
Initial commit for svn repository management and access control:...
r393 end
Jean-Philippe Lang
Added issues status changes on the activity view (initial patch by Cyril Mougel)....
r879
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 # returns latest created projects
# non public projects will be returned only if user is a member of those
def self.latest(user=nil, count=5)
Jean-Philippe Lang
Don't show projects created more than 30 days ago in "Latest projects" (#21148)....
r14472 visible(user).limit(count).
order(:created_on => :desc).
where("#{table_name}.created_on >= ?", 30.days.ago).
to_a
Toshi MARUYAMA
remove trailing tabs from app/models/project.rb...
r11185 end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330
Jean-Philippe Lang
Adds visibility condition on parent project in API....
r6084 # Returns true if the project is visible to +user+ or to the current user.
def visible?(user=User.current)
user.allowed_to?(:view_project, self)
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Makes visible scopes accept projects option and deprecate Project.visible_by....
r5204 # Returns a SQL conditions string used to find all projects visible by the specified user.
Eric Davis
Added some RDoc documentation for some models....
r2536 #
# Examples:
Jean-Philippe Lang
Makes visible scopes accept projects option and deprecate Project.visible_by....
r5204 # Project.visible_condition(admin) => "projects.status = 1"
# Project.visible_condition(normal_user) => "((projects.status = 1) AND (projects.is_public = 1 OR projects.id IN (1,3,4)))"
# Project.visible_condition(anonymous) => "((projects.status = 1) AND (projects.is_public = 1))"
def self.visible_condition(user, options={})
allowed_to_condition(user, :view_project, options)
Jean-Philippe Lang
Added the ability to archive projects:...
r546 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Makes visible scopes accept projects option and deprecate Project.visible_by....
r5204 # Returns a SQL conditions string used to find all projects for which +user+ has the given +permission+
#
# Valid options:
Jean-Philippe Lang
Adds updated_by and last_updated_by filters on issues (#17720)....
r15846 # * :skip_pre_condition => true don't check that the module is enabled (eg. when the condition is already set elsewhere in the query)
# * :project => project limit the condition to project
# * :with_subprojects => true limit the condition to project and its subprojects
# * :member => true limit the condition to the user projects
Jean-Philippe Lang
Activity enhancements:...
r1213 def self.allowed_to_condition(user, permission, options={})
Jean-Philippe Lang
Ability to close projects (read-only) (#3640)....
r9700 perm = Redmine::AccessControl.permission(permission)
base_statement = (perm && perm.read? ? "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED}" : "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}")
Jean-Philippe Lang
Adds updated_by and last_updated_by filters on issues (#17720)....
r15846 if !options[:skip_pre_condition] && perm && perm.project_module
Jean-Philippe Lang
Ability to close projects (read-only) (#3640)....
r9700 # If the permission belongs to a project module, make sure the module is enabled
Jean-Philippe Lang
Use EXISTS instead of IN subquery (#21608)....
r15860 base_statement << " AND EXISTS (SELECT 1 AS one FROM #{EnabledModule.table_name} em WHERE em.project_id = #{Project.table_name}.id AND em.name='#{perm.project_module}')"
Jean-Philippe Lang
Fixed: cross-project issue list should not show issues of projects for which the issue tracking module was disabled....
r1905 end
Jean-Philippe Lang
Code cleanup: use #project_condition....
r13115 if project = options[:project]
project_statement = project.project_condition(options[:with_subprojects])
Jean-Philippe Lang
Activity enhancements:...
r1213 base_statement = "(#{project_statement}) AND (#{base_statement})"
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Propagates time tracking to the parent project (closes #433). Time report enhancements....
r1162 if user.admin?
Jean-Philippe Lang
Changed the way the visibility SQL statement is built....
r5020 base_statement
Jean-Philippe Lang
Propagates time tracking to the parent project (closes #433). Time report enhancements....
r1162 else
Jean-Philippe Lang
Changed the way the visibility SQL statement is built....
r5020 statement_by_role = {}
Jean-Philippe Lang
Code cleanup....
r5339 unless options[:member]
Jean-Philippe Lang
Adds User#builtin_role....
r11735 role = user.builtin_role
Jean-Philippe Lang
Code cleanup....
r5339 if role.allowed_to?(permission)
Jean-Philippe Lang
Fixed that members without view issues permission are able to list issues on public projects if the non member role has the permission (#20206)....
r14068 s = "#{Project.table_name}.is_public = #{connection.quoted_true}"
if user.id
Jean-Philippe Lang
Fixed that restricted custom permissions on for non member/anonymous does not work (#23655). ...
r15368 group = role.anonymous? ? Group.anonymous : Group.non_member
principal_ids = [user.id, group.id].compact
s = "(#{s} AND #{Project.table_name}.id NOT IN (SELECT project_id FROM #{Member.table_name} WHERE user_id IN (#{principal_ids.join(',')})))"
Jean-Philippe Lang
Fixed that members without view issues permission are able to list issues on public projects if the non member role has the permission (#20206)....
r14068 end
statement_by_role[role] = s
Jean-Philippe Lang
Changed the way the visibility SQL statement is built....
r5020 end
Jean-Philippe Lang
Code cleanup....
r5339 end
Jean-Philippe Lang
Speeds up Project.allowed_to_condition for users who belong to hundreds of projects....
r15742 user.project_ids_by_role.each do |role, project_ids|
if role.allowed_to?(permission) && project_ids.any?
statement_by_role[role] = "#{Project.table_name}.id IN (#{project_ids.join(',')})"
Jean-Philippe Lang
Allow non admin users to add subprojects (#2963)....
r2945 end
Jean-Philippe Lang
Fixed: search engine may reveal private projects (#1613)....
r1635 end
Jean-Philippe Lang
Changed the way the visibility SQL statement is built....
r5020 if statement_by_role.empty?
"1=0"
else
Jean-Philippe Lang
Adds an issues visibility level on roles (#7412)....
r5296 if block_given?
statement_by_role.each do |role, statement|
if s = yield(role, user)
statement_by_role[role] = "(#{statement} AND (#{s}))"
end
end
end
Jean-Philippe Lang
Changed the way the visibility SQL statement is built....
r5020 "((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))"
end
Jean-Philippe Lang
Propagates time tracking to the parent project (closes #433). Time report enhancements....
r1162 end
end
Eric Davis
Added some RDoc documentation for some models....
r2536
Jean-Philippe Lang
Adds buit-in groups to give specific permissions to anonymous and non members users per project (#17976)....
r13053 def override_roles(role)
Jean-Philippe Lang
Deprecates Project#member_principals....
r13950 @override_members ||= memberships.
joins(:principal).
where(:users => {:type => ['GroupAnonymous', 'GroupNonMember']}).to_a
Jean-Philippe Lang
Memorize project override roles....
r13552
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 group_class = role.anonymous? ? GroupAnonymous : GroupNonMember
Jean-Philippe Lang
Memorize project override roles....
r13552 member = @override_members.detect {|m| m.principal.is_a? group_class}
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 member ? member.roles.to_a : [role]
Jean-Philippe Lang
Adds buit-in groups to give specific permissions to anonymous and non members users per project (#17976)....
r13053 end
Jean-Philippe Lang
Moves Project#principals to a regular method....
r11378 def principals
Jean-Philippe Lang
Use .distinct instead of .uniq....
r15272 @principals ||= Principal.active.joins(:members).where("#{Member.table_name}.project_id = ?", id).distinct
Jean-Philippe Lang
Moves Project#principals to a regular method....
r11378 end
Jean-Philippe Lang
Moves Project#users to a regular method....
r11379 def users
Jean-Philippe Lang
Use .distinct instead of .uniq....
r15272 @users ||= User.active.joins(:members).where("#{Member.table_name}.project_id = ?", id).distinct
Jean-Philippe Lang
Moves Project#users to a regular method....
r11379 end
Eric Davis
Added a Activities tab to Project Settings...
r2835 # Returns the Systemwide and project specific activities
def activities(include_inactive=false)
Jean-Philippe Lang
Fixed that project activity without parent hides system activities and removed duplicated code....
r13910 t = TimeEntryActivity.table_name
scope = TimeEntryActivity.where("#{t}.project_id IS NULL OR #{t}.project_id = ?", id)
overridden_activity_ids = self.time_entry_activities.pluck(:parent_id).compact
if overridden_activity_ids.any?
scope = scope.where("#{t}.id NOT IN (?)", overridden_activity_ids)
end
unless include_inactive
scope = scope.active
Eric Davis
Added a Activities tab to Project Settings...
r2835 end
Jean-Philippe Lang
Fixed that project activity without parent hides system activities and removed duplicated code....
r13910 scope
Eric Davis
Added a Activities tab to Project Settings...
r2835 end
Eric Davis
Changed the Timelogs to use both the Systemwide and Project specific TimeEntryActivities...
r2834
Eric Davis
When a specific TimeEntryActivity are change, associated TimeEntries will be...
r2836 # Will create a new Project specific Activity or update an existing one
#
# This will raise a ActiveRecord::Rollback if the TimeEntryActivity
# does not successfully save.
def update_or_create_time_entry_activity(id, activity_hash)
Eric Davis
Added a Activities tab to Project Settings...
r2835 if activity_hash.respond_to?(:has_key?) && activity_hash.has_key?('parent_id')
Eric Davis
When a specific TimeEntryActivity are change, associated TimeEntries will be...
r2836 self.create_time_entry_activity_if_needed(activity_hash)
Eric Davis
Changed the Timelogs to use both the Systemwide and Project specific TimeEntryActivities...
r2834 else
Eric Davis
Added a Activities tab to Project Settings...
r2835 activity = project.time_entry_activities.find_by_id(id.to_i)
activity.update_attributes(activity_hash) if activity
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Eric Davis
When a specific TimeEntryActivity are change, associated TimeEntries will be...
r2836 # Create a new TimeEntryActivity if it overrides a system TimeEntryActivity
#
# This will raise a ActiveRecord::Rollback if the TimeEntryActivity
# does not successfully save.
def create_time_entry_activity_if_needed(activity)
Eric Davis
Added a Activities tab to Project Settings...
r2835 if activity['parent_id']
parent_activity = TimeEntryActivity.find(activity['parent_id'])
activity['name'] = parent_activity.name
activity['position'] = parent_activity.position
Toshi MARUYAMA
fix typo of Enumeration#overridding_change?...
r12781 if Enumeration.overriding_change?(activity, parent_activity)
Eric Davis
When a specific TimeEntryActivity are change, associated TimeEntries will be...
r2836 project_activity = self.time_entry_activities.create(activity)
if project_activity.new_record?
Toshi MARUYAMA
fix typo of Enumeration#overridding_change?...
r12781 raise ActiveRecord::Rollback, "Overriding TimeEntryActivity was not successfully saved"
Eric Davis
When a specific TimeEntryActivity are change, associated TimeEntries will be...
r2836 else
Toshi MARUYAMA
Rails4: replace deprecated Relation#update_all at Project#create_time_entry_activity_if_needed...
r12339 self.time_entries.
Jean-Philippe Lang
Conditions cleanup....
r14310 where(:activity_id => parent_activity.id).
update_all(:activity_id => project_activity.id)
Eric Davis
When a specific TimeEntryActivity are change, associated TimeEntries will be...
r2836 end
Eric Davis
Added a Activities tab to Project Settings...
r2835 end
Eric Davis
Changed the Timelogs to use both the Systemwide and Project specific TimeEntryActivities...
r2834 end
end
Eric Davis
Added some RDoc documentation for some models....
r2536 # Returns a :conditions SQL string that can be used to find the issues associated with this project.
#
# Examples:
# project.project_condition(true) => "(projects.id = 1 OR (projects.lft > 1 AND projects.rgt < 10))"
# project.project_condition(false) => "projects.id = 1"
Jean-Philippe Lang
If 'Display subprojects issues on main projects' is set to false:...
r1283 def project_condition(with_subprojects)
cond = "#{Project.table_name}.id = #{id}"
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 cond = "(#{cond} OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt}))" if with_subprojects
Jean-Philippe Lang
If 'Display subprojects issues on main projects' is set to false:...
r1283 cond
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Project identifier is now used in URLs (instead of project id)....
r994 def self.find(*args)
if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
project = find_by_identifier(*args)
raise ActiveRecord::RecordNotFound, "Couldn't find Project with identifier=#{args.first}" if project.nil?
project
else
super
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Merged rails-3.2 branch....
r9346 def self.find_by_param(*args)
self.find(*args)
end
Jean-Philippe Lang
Fixed that #reload raises a Stack too deep error with ruby 2.0....
r11267 alias :base_reload :reload
Jean-Philippe Lang
Cleanup instance variables when reloading a project....
r8859 def reload(*args)
Jean-Philippe Lang
Moves Project#principals to a regular method....
r11378 @principals = nil
Jean-Philippe Lang
Moves Project#users to a regular method....
r11379 @users = nil
Jean-Philippe Lang
Cleanup instance variables when reloading a project....
r8859 @shared_versions = nil
@rolled_up_versions = nil
@rolled_up_trackers = nil
@all_issue_custom_fields = nil
@all_time_entry_custom_fields = nil
@to_param = nil
@allowed_parents = nil
@allowed_permissions = nil
@actions_allowed = nil
Jean-Philippe Lang
Gantt perf: fixed that Project#start_date and #due_date run way too much queries....
r10905 @start_date = nil
@due_date = nil
Jean-Philippe Lang
Adds buit-in groups to give specific permissions to anonymous and non members users per project (#17976)....
r13053 @override_members = nil
Jean-Philippe Lang
Clear @assignable_users on reload....
r13128 @assignable_users = nil
Jean-Philippe Lang
Fixed that #reload raises a Stack too deep error with ruby 2.0....
r11267 base_reload(*args)
Jean-Philippe Lang
Cleanup instance variables when reloading a project....
r8859 end
Jean-Philippe Lang
Project identifier is now used in URLs (instead of project id)....
r994 def to_param
Jean-Philippe Lang
Fixed invalid search link on the new project form (#20565)....
r14232 if new_record?
nil
else
# id is used for projects with a numeric identifier (compatibility)
@to_param ||= (identifier.to_s =~ %r{^\d*$} ? id.to_s : identifier)
end
Jean-Philippe Lang
Project identifier is now used in URLs (instead of project id)....
r994 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Added the ability to archive projects:...
r546 def active?
self.status == STATUS_ACTIVE
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Unarchive link not working for subprojects of closed projects (#24595)....
r15689 def closed?
self.status == STATUS_CLOSED
end
Jean-Philippe Lang
Improved error message when trying to access an archived project (#2995)....
r4171 def archived?
self.status == STATUS_ARCHIVED
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Version sharing (#465) + optional inclusion of subprojects in the roadmap view (#2666)....
r3009 # Archives the project and its descendants
Jean-Philippe Lang
Added the ability to archive projects:...
r546 def archive
Jean-Philippe Lang
Version sharing (#465) + optional inclusion of subprojects in the roadmap view (#2666)....
r3009 # Check that there is no issue of a non descendant project that is assigned
# to one of the project or descendant versions
Jean-Philippe Lang
Get version ids with a single query (was n+1)....
r13312 version_ids = self_and_descendants.joins(:versions).pluck("#{Version.table_name}.id")
if version_ids.any? &&
Jean-Philippe Lang
Replaces find(:first) calls....
r10701 Issue.
includes(:project).
where("#{Project.table_name}.lft < ? OR #{Project.table_name}.rgt > ?", lft, rgt).
Jean-Philippe Lang
Get version ids with a single query (was n+1)....
r13312 where(:fixed_version_id => version_ids).
Jean-Philippe Lang
Replaces find(:first) calls....
r10701 exists?
Jean-Philippe Lang
Version sharing (#465) + optional inclusion of subprojects in the roadmap view (#2666)....
r3009 return false
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 end
Jean-Philippe Lang
Version sharing (#465) + optional inclusion of subprojects in the roadmap view (#2666)....
r3009 Project.transaction do
archive!
end
true
Jean-Philippe Lang
Added the ability to archive projects:...
r546 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 # Unarchives the project
# All its ancestors must be active
Jean-Philippe Lang
Added the ability to archive projects:...
r546 def unarchive
Jean-Philippe Lang
Unarchive link not working for subprojects of closed projects (#24595)....
r15689 return false if ancestors.detect {|a| a.archived?}
new_status = STATUS_ACTIVE
if parent
new_status = parent.status
end
update_attribute :status, new_status
Jean-Philippe Lang
Added the ability to archive projects:...
r546 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Ability to close projects (read-only) (#3640)....
r9700 def close
self_and_descendants.status(STATUS_ACTIVE).update_all :status => STATUS_CLOSED
end
def reopen
self_and_descendants.status(STATUS_CLOSED).update_all :status => STATUS_ACTIVE
end
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 # Returns an array of projects the project can be moved to
Jean-Philippe Lang
Allow non admin users to add subprojects (#2963)....
r2945 # by the current user
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 def allowed_parents(user=User.current)
Jean-Philippe Lang
Allow non admin users to add subprojects (#2963)....
r2945 return @allowed_parents if @allowed_parents
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 @allowed_parents = Project.allowed_to(user, :add_subprojects).to_a
Jean-Philippe Lang
Adds a 'Add subprojects' permission....
r3124 @allowed_parents = @allowed_parents - self_and_descendants
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 if user.allowed_to?(:add_project, nil, :global => true) || (!new_record? && parent.nil?)
Jean-Philippe Lang
Adds a 'Add subprojects' permission....
r3124 @allowed_parents << nil
end
Jean-Philippe Lang
Allow non admin users to add subprojects (#2963)....
r2945 unless parent.nil? || @allowed_parents.empty? || @allowed_parents.include?(parent)
@allowed_parents << parent
end
@allowed_parents
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Allow non admin users to add subprojects (#2963)....
r2945 # Sets the parent of the project with authorization check
def set_allowed_parent!(p)
Jean-Philippe Lang
Deprecates Project#set_allowed_parent!....
r13467 ActiveSupport::Deprecation.warn "Project#set_allowed_parent! is deprecated and will be removed in Redmine 4, use #safe_attributes= instead."
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 p = p.id if p.is_a?(Project)
send :safe_attributes, {:project_id => p}
save
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Deprecates Project#set_allowed_parent!....
r13467 # Sets the parent of the project and saves the project
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 # Argument can be either a Project, a String, a Fixnum or nil
def set_parent!(p)
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 if p.is_a?(Project)
Jean-Philippe Lang
Replaces awesome_nested_set gem with a simple and more robust implementation of nested sets....
r13459 self.parent = p
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 else
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 self.parent_id = p
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 end
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 save
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Limits the tracker list in filters and issue counts (#285)....
r15158 # Returns a scope of the trackers used by the project and its active sub projects
def rolled_up_trackers(include_subprojects=true)
if include_subprojects
@rolled_up_trackers ||= rolled_up_trackers_base_scope.
where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ?", lft, rgt)
else
rolled_up_trackers_base_scope.
where(:projects => {:id => id})
end
end
def rolled_up_trackers_base_scope
Tracker.
joins(projects: :enabled_modules).
where("#{Project.table_name}.status <> ?", STATUS_ARCHIVED).
where(:enabled_modules => {:name => 'issue_tracking'}).
Jean-Philippe Lang
Use .distinct instead of .uniq....
r15272 distinct.
Jean-Philippe Lang
Limits the tracker list in filters and issue counts (#285)....
r15158 sorted
Jean-Philippe Lang
On the calendar, the gantt and in the Tracker filter on the issue list, only active trackers of the project (and its sub projects) can be selected....
r1057 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Adds a link to automatically close completed versions in project settings (#1245)....
r2909 # Closes open and locked project versions that are completed
def close_completed_versions
Version.transaction do
Toshi MARUYAMA
remove unneeded Relation#all from Project model...
r12454 versions.where(:status => %w(open locked)).each do |version|
Jean-Philippe Lang
Adds a link to automatically close completed versions in project settings (#1245)....
r2909 if version.completed?
version.update_attribute(:status, 'closed')
end
end
end
end
Eric Davis
Show subproject versions on the Roadmap....
r3646
# Returns a scope of the Versions on subprojects
def rolled_up_versions
@rolled_up_versions ||=
Jean-Philippe Lang
Code cleanup....
r11643 Version.
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 joins(:project).
Jean-Philippe Lang
Code cleanup....
r11643 where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> ?", lft, rgt, STATUS_ARCHIVED)
Eric Davis
Show subproject versions on the Roadmap....
r3646 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Version sharing (#465) + optional inclusion of subprojects in the roadmap view (#2666)....
r3009 # Returns a scope of the Versions used by the project
def shared_versions
Jean-Philippe Lang
Fixed: error when creating a project with a version format custom field (#10218)....
r8745 if new_record?
Jean-Philippe Lang
Code cleanup....
r11643 Version.
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 joins(:project).
preload(:project).
Jean-Philippe Lang
Code cleanup....
r11643 where("#{Project.table_name}.status <> ? AND #{Version.table_name}.sharing = 'system'", STATUS_ARCHIVED)
Jean-Philippe Lang
Fixed: error when creating a project with a version format custom field (#10218)....
r8745 else
@shared_versions ||= begin
r = root? ? self : root
Jean-Philippe Lang
Code cleanup....
r11643 Version.
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 joins(:project).
preload(:project).
Jean-Philippe Lang
Code cleanup....
r11643 where("#{Project.table_name}.id = #{id}" +
" OR (#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND (" +
" #{Version.table_name}.sharing = 'system'" +
" OR (#{Project.table_name}.lft >= #{r.lft} AND #{Project.table_name}.rgt <= #{r.rgt} AND #{Version.table_name}.sharing = 'tree')" +
" OR (#{Project.table_name}.lft < #{lft} AND #{Project.table_name}.rgt > #{rgt} AND #{Version.table_name}.sharing IN ('hierarchy', 'descendants'))" +
" OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt} AND #{Version.table_name}.sharing = 'hierarchy')" +
"))")
Jean-Philippe Lang
Fixed: error when creating a project with a version format custom field (#10218)....
r8745 end
Jean-Philippe Lang
Save 1 query + 1 cache hit in #shared_versions for root projects....
r5123 end
Jean-Philippe Lang
Version sharing (#465) + optional inclusion of subprojects in the roadmap view (#2666)....
r3009 end
Jean-Philippe Lang
Display all users roles on project overview (#3339)....
r2635 # Returns a hash of project users grouped by role
def users_by_role
Toshi MARUYAMA
remove unneeded Relation#all from Project model...
r12454 members.includes(:user, :roles).inject({}) do |h, m|
Jean-Philippe Lang
Display all users roles on project overview (#3339)....
r2635 m.roles.each do |r|
h[r] ||= []
h[r] << m.user
end
h
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Moved controller code to new method Project#add_default_member....
r13160 # Adds user as a project member with the default role
# Used for when a non-admin user creates a project
def add_default_member(user)
Jean-Philippe Lang
Disable "Select project modules" permission does not apply to the new project form (#23470)....
r15370 role = self.class.default_member_role
Jean-Philippe Lang
Moved controller code to new method Project#add_default_member....
r13160 member = Member.new(:project => self, :principal => user, :roles => [role])
self.members << member
member
end
Jean-Philippe Lang
Disable "Select project modules" permission does not apply to the new project form (#23470)....
r15370 # Default role that is given to non-admin users that
# create a project
def self.default_member_role
Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first
end
Jean-Philippe Lang
Merged Rails 2.0 compatibility changes....
r962 # Deletes all project's members
def delete_all_members
Jean-Philippe Lang
Allows multiple roles on the same project (#706). Prerequisite for user groups feature....
r2627 me, mr = Member.table_name, MemberRole.table_name
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 self.class.connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.project_id = #{id})")
Jean-Philippe Lang
Don't pass conditions to #delete_all....
r15293 Member.where(:project_id => id).delete_all
Jean-Philippe Lang
Merged Rails 2.0 compatibility changes....
r962 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Makes Project#assignable_users return a scope that prevents 2*n queries....
r13127 # Return a Principal scope of users/groups issues can be assigned to
Jean-Philippe Lang
Assignable users should not include users that cannot view the tracker (#23172)....
r15204 def assignable_users(tracker=nil)
return @assignable_users[tracker] if @assignable_users && @assignable_users[tracker]
Jean-Philippe Lang
Adds buit-in groups to give specific permissions to anonymous and non members users per project (#17976)....
r13053 types = ['User']
types << 'Group' if Setting.issue_group_assignment?
Jean-Philippe Lang
Assignable users should not include users that cannot view the tracker (#23172)....
r15204 scope = Principal.
Jean-Philippe Lang
Makes Project#assignable_users return a scope that prevents 2*n queries....
r13127 active.
joins(:members => :roles).
where(:type => types, :members => {:project_id => id}, :roles => {:assignable => true}).
Jean-Philippe Lang
Use .distinct instead of .uniq....
r15272 distinct.
Jean-Philippe Lang
Makes Project#assignable_users return a scope that prevents 2*n queries....
r13127 sorted
Jean-Philippe Lang
Assignable users should not include users that cannot view the tracker (#23172)....
r15204
if tracker
# Rejects users that cannot the view the tracker
roles = Role.where(:assignable => true).select {|role| role.permissions_tracker?(:view_issues, tracker)}
scope = scope.where(:roles => {:id => roles.map(&:id)})
end
@assignable_users ||= {}
@assignable_users[tracker] = scope
Jean-Philippe Lang
Added 'Bulk edit' functionality....
r806 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Toshi MARUYAMA
fix typos of source comments at Project model...
r12782 # Returns the mail addresses of users that should be always notified on project events
Jean-Philippe Lang
More flexible mail notifications settings at user level. A user has now 3 options:...
r842 def recipients
Eric Davis
Change Project#notified_users to check for the 'all' notification option. #6541...
r4133 notified_users.collect {|user| user.mail}
Jean-Philippe Lang
More flexible mail notifications settings at user level. A user has now 3 options:...
r842 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Do not notify users that are no longer allowed to view an issue (#3589, #4263)....
r3007 # Returns the users that should be notified on project events
def notified_users
Eric Davis
Change Project#notified_users to check for the 'all' notification option. #6541...
r4133 # TODO: User part should be extracted to User#notify_about?
Jean-Philippe Lang
Preload principals....
r15136 members.preload(:principal).select {|m| m.principal.present? && (m.mail_notification? || m.principal.mail_notification == 'all')}.collect {|m| m.principal}
Jean-Philippe Lang
Do not notify users that are no longer allowed to view an issue (#3589, #4263)....
r3007 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Project#all_issue_custom_fields now returns a scope....
r11686 # Returns a scope of all custom fields enabled for project issues
Toshi MARUYAMA
fix typos of source comments at Project model...
r12782 # (explicitly associated custom fields and custom fields enabled for all projects)
Jean-Philippe Lang
Custom fields refactoring: most of code moved from controllers to models (using new module ActsAsCustomizable)....
r1578 def all_issue_custom_fields
Jean-Philippe Lang
Project copy does not copy custom field settings (#20360)....
r14236 if new_record?
@all_issue_custom_fields ||= IssueCustomField.
sorted.
where("is_for_all = ? OR id IN (?)", true, issue_custom_field_ids)
else
@all_issue_custom_fields ||= IssueCustomField.
sorted.
where("is_for_all = ? OR id IN (SELECT DISTINCT cfp.custom_field_id" +
" FROM #{table_name_prefix}custom_fields_projects#{table_name_suffix} cfp" +
" WHERE cfp.project_id = ?)", true, id)
end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330 end
Toshi MARUYAMA
add bulk edit and bulk update actions for time entries (#7996)....
r5193
Jean-Philippe Lang
Ability to search all projects or the projects the user belongs to (#791)....
r1420 def project
self
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Subprojects are now grouped by projects in the 'Projects' top navigation drop-down menu....
r692 def <=>(project)
Toshi MARUYAMA
use String#casecmp for case insensitive comparison (#20369)...
r14102 name.casecmp(project.name)
Jean-Philippe Lang
Subprojects are now grouped by projects in the 'Projects' top navigation drop-down menu....
r692 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Unlimited and optional project description. The project list will show truncated descriptions only (the first fews lines)....
r1074 def to_s
name
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Unlimited and optional project description. The project list will show truncated descriptions only (the first fews lines)....
r1074 # Returns a short description of the projects (first lines)
def short_description(length = 255)
Jean-Philippe Lang
Merged nested projects branch. Removes limit on subproject nesting (#594)....
r2302 description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description
Jean-Philippe Lang
Unlimited and optional project description. The project list will show truncated descriptions only (the first fews lines)....
r1074 end
Eric Davis
Rewrite the Gantt chart. #6276...
r3958
Eric Davis
Refactor: move method to Project#css_classes...
r3966 def css_classes
s = 'project'
s << ' root' if root?
s << ' child' if child?
s << (leaf? ? ' leaf' : ' parent')
Jean-Philippe Lang
Ability to close projects (read-only) (#3640)....
r9700 unless active?
if archived?
s << ' archived'
else
s << ' closed'
end
end
Eric Davis
Refactor: move method to Project#css_classes...
r3966 s
end
Eric Davis
Rewrite the Gantt chart. #6276...
r3958 # The earliest start date of a project, based on it's issues and versions
def start_date
Jean-Philippe Lang
Gantt perf: fixed that Project#start_date and #due_date run way too much queries....
r10905 @start_date ||= [
Jean-Philippe Lang
Select projects with issue_tracking module for gantt display and remove the nil start/due dates trick....
r4363 issues.minimum('start_date'),
Jean-Philippe Lang
Gantt perf: fixed that Project#start_date and #due_date run way too much queries....
r10905 shared_versions.minimum('effective_date'),
Issue.fixed_version(shared_versions).minimum('start_date')
].compact.min
Eric Davis
Rewrite the Gantt chart. #6276...
r3958 end
Eric Davis
Revert "Fixed: gantt broken when no due date on project issues and versions."...
r4070 # The latest due date of an issue or version
Eric Davis
Rewrite the Gantt chart. #6276...
r3958 def due_date
Jean-Philippe Lang
Gantt perf: fixed that Project#start_date and #due_date run way too much queries....
r10905 @due_date ||= [
Jean-Philippe Lang
Select projects with issue_tracking module for gantt display and remove the nil start/due dates trick....
r4363 issues.maximum('due_date'),
Jean-Philippe Lang
Gantt perf: fixed that Project#start_date and #due_date run way too much queries....
r10905 shared_versions.maximum('effective_date'),
Issue.fixed_version(shared_versions).maximum('due_date')
].compact.max
Eric Davis
Rewrite the Gantt chart. #6276...
r3958 end
def overdue?
Jean-Philippe Lang
Replace Date.today with User.current.today (#22320)....
r14997 active? && !due_date.nil? && (due_date < User.current.today)
Eric Davis
Rewrite the Gantt chart. #6276...
r3958 end
# Returns the percent completed for this project, based on the
# progress on it's versions.
def completed_percent(options={:include_subprojects => false})
if options.delete(:include_subprojects)
total = self_and_descendants.collect(&:completed_percent).sum
total / self_and_descendants.count
else
if versions.count > 0
Jean-Philippe Lang
Deprecates Version#*_pourcent in favour of #*_percent (#12724)....
r10883 total = versions.collect(&:completed_percent).sum
Eric Davis
Rewrite the Gantt chart. #6276...
r3958
total / versions.count
else
100
end
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Moved logic relative to project status from User to Project model (#3640)....
r9703 # Return true if this project allows to do the specified action.
Eric Davis
Added some RDoc documentation for some models....
r2536 # action can be:
# * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
# * a permission Symbol (eg. :edit_project)
Jean-Philippe Lang
Added project module concept....
r714 def allows_to?(action)
Jean-Philippe Lang
Moved logic relative to project status from User to Project model (#3640)....
r9703 if archived?
# No action allowed on archived projects
return false
end
unless active? || Redmine::AccessControl.read_action?(action)
# No write action allowed on closed projects
return false
end
# No action allowed on disabled modules
Jean-Philippe Lang
Added project module concept....
r714 if action.is_a? Hash
allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
else
allowed_permissions.include? action
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Use spaces instead of tabs....
r12592 # Return the enabled module with the given name
# or nil if the module is not enabled for the project
Jean-Philippe Lang
Enable the watching of news (#2549)....
r12591 def enabled_module(name)
name = name.to_s
enabled_modules.detect {|m| m.name == name}
end
Jean-Philippe Lang
Use spaces instead of tabs....
r12592 # Return true if the module with the given name is enabled
Jean-Philippe Lang
Enable the watching of news (#2549)....
r12591 def module_enabled?(name)
enabled_module(name).present?
Jean-Philippe Lang
Added project module concept....
r714 end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Added project module concept....
r714 def enabled_module_names=(module_names)
Jean-Philippe Lang
Do not DELETE/INSERT enabled_modules when updating project modules....
r2412 if module_names && module_names.is_a?(Array)
Jean-Philippe Lang
Moves project attributes default assignments from ProjectsController#new to the model (#6064)....
r4346 module_names = module_names.collect(&:to_s).reject(&:blank?)
Jean-Philippe Lang
Modules selection lost on project form after validation failure (#8012)....
r5145 self.enabled_modules = module_names.collect {|name| enabled_modules.detect {|mod| mod.name == name} || EnabledModule.new(:name => name)}
Jean-Philippe Lang
Do not DELETE/INSERT enabled_modules when updating project modules....
r2412 else
enabled_modules.clear
Jean-Philippe Lang
Added project module concept....
r714 end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Moves project attributes default assignments from ProjectsController#new to the model (#6064)....
r4346 # Returns an array of the enabled modules names
def enabled_module_names
enabled_modules.collect(&:name)
end
Jean-Baptiste Barth
Added Project#enable_module! and Project#disable_module! (#7115)...
r5978
# Enable a specific module
#
# Examples:
# project.enable_module!(:issue_tracking)
# project.enable_module!("issue_tracking")
def enable_module!(name)
enabled_modules << EnabledModule.new(:name => name.to_s) unless module_enabled?(name)
end
# Disable a module if it exists
#
# Examples:
# project.disable_module!(:issue_tracking)
# project.disable_module!("issue_tracking")
# project.disable_module!(project.enabled_modules.first)
def disable_module!(target)
target = enabled_modules.detect{|mod| target.to_s == mod.name} unless enabled_modules.include?(target)
target.destroy unless target.blank?
end
Jean-Philippe Lang
Declare safe attributes for User and Projects models....
r4378 safe_attributes 'name',
'description',
'homepage',
'is_public',
'identifier',
'custom_field_values',
'custom_fields',
Jean-Philippe Lang
Fixed: r4492 breaks the ability to select issue custom fields available for projects issues (#7121)....
r4415 'tracker_ids',
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 'issue_custom_field_ids',
Jean-Philippe Lang
Default target version for new issues (#1828)....
r14404 'parent_id',
'default_version_id'
Eric Davis
Change the TimelogController's to/from dates based on the project time entries...
r3973
Jean-Philippe Lang
Moves enabled_module_names param to project attribute so that it can be set through the Project API....
r4525 safe_attributes 'enabled_module_names',
Jean-Philippe Lang
Disable "Select project modules" permission does not apply to the new project form (#23470)....
r15370 :if => lambda {|project, user|
if project.new_record?
if user.admin?
true
else
default_member_role.has_permission?(:select_project_modules)
end
else
user.allowed_to?(:select_project_modules, project)
end
}
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Optionaly inherit members from parent project (#5605)....
r11068 safe_attributes 'inherit_members',
Jean-Philippe Lang
Typo that triggers an error when editing a subproject (#5605)....
r11071 :if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)}
Jean-Philippe Lang
Optionaly inherit members from parent project (#5605)....
r11068
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 def safe_attributes=(attrs, user=User.current)
return unless attrs.is_a?(Hash)
attrs = attrs.deep_dup
@unallowed_parent_id = nil
Jean-Philippe Lang
Error message when editing a child project without add project/subprojects permissions (#20282)....
r14237 if new_record? || attrs.key?('parent_id')
parent_id_param = attrs['parent_id'].to_s
if new_record? || parent_id_param != parent_id.to_s
p = parent_id_param.present? ? Project.find_by_id(parent_id_param) : nil
unless allowed_parents(user).include?(p)
attrs.delete('parent_id')
@unallowed_parent_id = true
end
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 end
end
super(attrs, user)
end
Jean-Philippe Lang
Adds an option to generate sequential project identifiers....
r1776 # Returns an auto-generated project identifier based on the last identifier used
def self.next_identifier
Toshi MARUYAMA
fix that project auto generation fails when projects created in the same time (#14242)...
r11712 p = Project.order('id DESC').first
Jean-Philippe Lang
Adds an option to generate sequential project identifiers....
r1776 p.nil? ? nil : p.identifier.to_s.succ
end
Jean-Philippe Lang
added svn:eol-style native property on /app files...
r330
Eric Davis
Added the ability to copy a project in the Project Administration panel....
r2608 # Copies and saves the Project instance based on the +project+.
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 # Duplicates the source project's:
# * Wiki
# * Versions
# * Categories
Eric Davis
Added the ability to copy a project in the Project Administration panel....
r2608 # * Issues
# * Members
# * Queries
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 #
# Accepts an +options+ argument to specify what to copy
#
# Examples:
# project.copy(1) # => copies everything
# project.copy(1, :only => 'members') # => copies members only
# project.copy(1, :only => ['members', 'versions']) # => copies members and versions
def copy(project, options={})
Eric Davis
Added the ability to copy a project in the Project Administration panel....
r2608 project = project.is_a?(Project) ? project : Project.find(project)
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Enforce issue assignee validation (#23921)....
r15673 to_be_copied = %w(members wiki versions issue_categories issues queries boards)
Jean-Philippe Lang
Merged rails-4.1 branch (#14534)....
r13100 to_be_copied = to_be_copied & Array.wrap(options[:only]) unless options[:only].nil?
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 Project.transaction do
Jean-Philippe Lang
Fixes project wiki copy....
r2855 if save
reload
to_be_copied.each do |name|
send "copy_#{name}", project
end
Redmine::Hook.call_hook(:model_project_copy_before_save, :source_project => project, :destination_project => self)
save
Jean-Philippe Lang
Fixed that project copy triggers a 500 error if project validation fails....
r13466 else
false
Eric Davis
Added the ability to copy a project in the Project Administration panel....
r2608 end
end
end
Jean-Philippe Lang
Deprecates Project#member_principals....
r13950 def member_principals
ActiveSupport::Deprecation.warn "Project#member_principals is deprecated and will be removed in Redmine 4.0. Use #memberships.active instead."
memberships.active
end
Jean-Philippe Lang
Code cleanup....
r10712 # Returns a new unsaved Project instance with attributes copied from +project+
Eric Davis
Added the ability to copy a project in the Project Administration panel....
r2608 def self.copy_from(project)
Jean-Philippe Lang
Code cleanup....
r10712 project = project.is_a?(Project) ? project : Project.find(project)
# clear unique attributes
attributes = project.attributes.dup.except('id', 'name', 'identifier', 'status', 'parent_id', 'lft', 'rgt')
copy = Project.new(attributes)
Jean-Philippe Lang
Project.copy_from deletes enabled_modules on source (#20512)....
r14126 copy.enabled_module_names = project.enabled_module_names
Jean-Philippe Lang
Code cleanup....
r10712 copy.trackers = project.trackers
copy.custom_values = project.custom_values.collect {|v| v.clone}
copy.issue_custom_fields = project.issue_custom_fields
copy
Eric Davis
Added the ability to copy a project in the Project Administration panel....
r2608 end
Eric Davis
Refactor: move method to model with compatibility wrapper...
r4168
# Yields the given block for each project with its level in the tree
Jean-Philippe Lang
Adds pagination to admin project list....
r15373 def self.project_tree(projects, options={}, &block)
Eric Davis
Refactor: move method to model with compatibility wrapper...
r4168 ancestors = []
Jean-Philippe Lang
Adds pagination to admin project list....
r15373 if options[:init_level] && projects.first
ancestors = projects.first.ancestors.to_a
end
Eric Davis
Refactor: move method to model with compatibility wrapper...
r4168 projects.sort_by(&:lft).each do |project|
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397 while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
Eric Davis
Refactor: move method to model with compatibility wrapper...
r4168 ancestors.pop
end
yield project, ancestors.size
ancestors << project
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 private
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Optionaly inherit members from parent project (#5605)....
r11068 def update_inherited_members
if parent
if inherit_members? && !inherit_members_was
remove_inherited_member_roles
add_inherited_member_roles
elsif !inherit_members? && inherit_members_was
remove_inherited_member_roles
end
end
end
def remove_inherited_member_roles
Jean-Philippe Lang
Speedup remove_inherited_roles (#22850)....
r15501 member_roles = MemberRole.where(:member_id => membership_ids).to_a
Jean-Philippe Lang
Optionaly inherit members from parent project (#5605)....
r11068 member_role_ids = member_roles.map(&:id)
member_roles.each do |member_role|
if member_role.inherited_from && !member_role_ids.include?(member_role.inherited_from)
member_role.destroy
end
end
end
def add_inherited_member_roles
if inherit_members? && parent
parent.memberships.each do |parent_member|
member = Member.find_or_new(self.id, parent_member.user_id)
parent_member.member_roles.each do |parent_member_role|
member.member_roles << MemberRole.new(:role => parent_member_role.role, :inherited_from => parent_member_role.id)
end
member.save!
end
Jean-Philippe Lang
Replaces awesome_nested_set gem with a simple and more robust implementation of nested sets....
r13459 memberships.reset
Jean-Philippe Lang
Optionaly inherit members from parent project (#5605)....
r11068 end
end
Jean-Philippe Lang
Cleans up parent project assignment in ProjectsController....
r13465 def update_versions_from_hierarchy_change
Issue.update_versions_from_hierarchy_change(self)
end
def validate_parent
if @unallowed_parent_id
errors.add(:parent_id, :invalid)
elsif parent_id_changed?
unless parent.nil? || (parent.active? && move_possible?(parent))
errors.add(:parent_id, :invalid)
end
end
end
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 # Copies wiki from +project+
def copy_wiki(project)
Jean-Philippe Lang
Fixes project wiki copy....
r2855 # Check that the source project has a wiki first
unless project.wiki.nil?
Jean-Philippe Lang
Fixed: error raised when copying project wiki with wiki module disabled (#13097)....
r11102 wiki = self.wiki || Wiki.new
Jean-Philippe Lang
Prevent mass-assignment warnings....
r2857 wiki.attributes = project.wiki.attributes.dup.except("id", "project_id")
Jean-Philippe Lang
Fixed: Project copy loses wiki pages hierarchy (#4797)....
r3298 wiki_pages_map = {}
Jean-Philippe Lang
Fixes project wiki copy....
r2855 project.wiki.pages.each do |page|
Jean-Philippe Lang
Fixed: Project copy loses wiki pages hierarchy (#4797)....
r3298 # Skip pages without content
next if page.content.nil?
Jean-Philippe Lang
Reset timestamps and wiki page hierarchy on project copy....
r2858 new_wiki_content = WikiContent.new(page.content.attributes.dup.except("id", "page_id", "updated_on"))
new_wiki_page = WikiPage.new(page.attributes.dup.except("id", "wiki_id", "created_on", "parent_id"))
Jean-Philippe Lang
Fixes project wiki copy....
r2855 new_wiki_page.content = new_wiki_content
wiki.pages << new_wiki_page
Jean-Philippe Lang
Fixed: Project copy loses wiki pages hierarchy (#4797)....
r3298 wiki_pages_map[page.id] = new_wiki_page
end
Jean-Philippe Lang
Fixed: error raised when copying project wiki with wiki module disabled (#13097)....
r11102
self.wiki = wiki
Jean-Philippe Lang
Fixed: Project copy loses wiki pages hierarchy (#4797)....
r3298 wiki.save
# Reproduce page hierarchy
project.wiki.pages.each do |page|
if page.parent_id && wiki_pages_map[page.id]
wiki_pages_map[page.id].parent = wiki_pages_map[page.parent_id]
wiki_pages_map[page.id].save
end
Jean-Philippe Lang
Fixes project wiki copy....
r2855 end
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 end
end
# Copies versions from +project+
def copy_versions(project)
project.versions.each do |version|
new_version = Version.new
Jean-Philippe Lang
Reset timestamps and wiki page hierarchy on project copy....
r2858 new_version.attributes = version.attributes.dup.except("id", "project_id", "created_on", "updated_on")
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 self.versions << new_version
end
end
# Copies issue categories from +project+
def copy_issue_categories(project)
project.issue_categories.each do |issue_category|
new_issue_category = IssueCategory.new
Jean-Philippe Lang
Prevent mass-assignment warnings....
r2857 new_issue_category.attributes = issue_category.attributes.dup.except("id", "project_id")
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 self.issue_categories << new_issue_category
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 # Copies issues from +project+
def copy_issues(project)
Eric Davis
Copy issue relations when copying a project. (#3367)...
r3050 # Stores the source issue id as a key and the copied issues as the
Toshi MARUYAMA
fix typos of source comments at Project model...
r12800 # value. Used to map the two together for issue relations.
Eric Davis
Copy issue relations when copying a project. (#3367)...
r3050 issues_map = {}
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Fixed: Issues associated with a locked version are not copied when copying a project (#11207)....
r10151 # Store status and reopen locked/closed versions
version_statuses = versions.reject(&:open?).map {|version| [version, version.status]}
version_statuses.each do |version, status|
version.update_attribute :status, 'open'
end
Jean-Philippe Lang
Adds subtasking (#443) including:...
r3459 # Get issues sorted by root_id, lft so that parent issues
# get copied before their children
Toshi MARUYAMA
remove unneeded Relation#all from Project#copy_issues...
r12266 project.issues.reorder('root_id, lft').each do |issue|
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 new_issue = Issue.new
Jean-Philippe Lang
Do not link copied issues when copying a project (#6899)....
r10286 new_issue.copy_from(issue, :subtasks => false, :link => false)
Jean-Philippe Lang
Adds subtasking (#443) including:...
r3459 new_issue.project = self
Jean-Philippe Lang
Fixed that values of custom fields are not kept in issues when copying a project (#13910)....
r11613 # Changing project resets the custom field values
# TODO: handle this in Issue#project=
new_issue.custom_field_values = issue.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
Jean-Philippe Lang
Code cleanup....
r10149 # Reassign fixed_versions by name, since names are unique per project
Jean-Philippe Lang
Fixed that target version is lost on project copy for issues that are assigned to a shared version from another project....
r10150 if issue.fixed_version && issue.fixed_version.project == project
Jean-Philippe Lang
Code cleanup....
r10149 new_issue.fixed_version = self.versions.detect {|v| v.name == issue.fixed_version.name}
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 end
Jean-Philippe Lang
Project copy does not update custom field of version type values (#20361)....
r14233 # Reassign version custom field values
new_issue.custom_field_values.each do |custom_value|
if custom_value.custom_field.field_format == 'version' && custom_value.value.present?
versions = Version.where(:id => custom_value.value).to_a
new_value = versions.map do |version|
if version.project == project
self.versions.detect {|v| v.name == version.name}.try(:id)
else
version.id
end
end
new_value.compact!
new_value = new_value.first unless custom_value.custom_field.multiple?
custom_value.value = new_value
end
end
Jean-Philippe Lang
Code cleanup....
r10149 # Reassign the category by name, since names are unique per project
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 if issue.category
Jean-Philippe Lang
Code cleanup....
r10149 new_issue.category = self.issue_categories.detect {|c| c.name == issue.category.name}
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 end
Jean-Philippe Lang
Adds subtasking (#443) including:...
r3459 # Parent issue
if issue.parent_id
if copied_parent = issues_map[issue.parent_id]
new_issue.parent_issue_id = copied_parent.id
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 self.issues << new_issue
Jean-Philippe Lang
Do not try to copy relations for issues that could not be copied....
r4370 if new_issue.new_record?
Jean-Philippe Lang
Use logger.info? (#18605)....
r13384 logger.info "Project#copy_issues: issue ##{issue.id} could not be copied: #{new_issue.errors.full_messages}" if logger && logger.info?
Jean-Philippe Lang
Do not try to copy relations for issues that could not be copied....
r4370 else
issues_map[issue.id] = new_issue unless new_issue.new_record?
end
Eric Davis
Copy issue relations when copying a project. (#3367)...
r3050 end
Jean-Philippe Lang
Fixed: Issues associated with a locked version are not copied when copying a project (#11207)....
r10151 # Restore locked/closed version statuses
version_statuses.each do |version, status|
version.update_attribute :status, status
end
Eric Davis
Copy issue relations when copying a project. (#3367)...
r3050 # Relations after in case issues related each other
project.issues.each do |issue|
new_issue = issues_map[issue.id]
Jean-Philippe Lang
Do not try to copy relations for issues that could not be copied....
r4370 unless new_issue
# Issue was not copied
next
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Eric Davis
Copy issue relations when copying a project. (#3367)...
r3050 # Relations
issue.relations_from.each do |source_relation|
new_issue_relation = IssueRelation.new
new_issue_relation.attributes = source_relation.attributes.dup.except("id", "issue_from_id", "issue_to_id")
new_issue_relation.issue_to = issues_map[source_relation.issue_to_id]
if new_issue_relation.issue_to.nil? && Setting.cross_project_issue_relations?
new_issue_relation.issue_to = source_relation.issue_to
end
new_issue.relations_from << new_issue_relation
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Eric Davis
Copy issue relations when copying a project. (#3367)...
r3050 issue.relations_to.each do |source_relation|
new_issue_relation = IssueRelation.new
new_issue_relation.attributes = source_relation.attributes.dup.except("id", "issue_from_id", "issue_to_id")
new_issue_relation.issue_from = issues_map[source_relation.issue_from_id]
if new_issue_relation.issue_from.nil? && Setting.cross_project_issue_relations?
new_issue_relation.issue_from = source_relation.issue_from
end
new_issue.relations_to << new_issue_relation
end
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 end
end
# Copies members from +project+
def copy_members(project)
Jean-Philippe Lang
Additional roles of a user who belongs to a group are not always copied when copying the project (#7213)....
r4495 # Copy users first, then groups to handle members with inherited and given roles
members_to_copy = []
members_to_copy += project.memberships.select {|m| m.principal.is_a?(User)}
members_to_copy += project.memberships.select {|m| !m.principal.is_a?(User)}
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Additional roles of a user who belongs to a group are not always copied when copying the project (#7213)....
r4495 members_to_copy.each do |member|
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 new_member = Member.new
Jean-Philippe Lang
Reset timestamps and wiki page hierarchy on project copy....
r2858 new_member.attributes = member.attributes.dup.except("id", "project_id", "created_on")
Jean-Philippe Lang
Fixed: project copy doesn't copy group memberships (#3975)....
r3136 # only copy non inherited roles
# inherited roles will be added when copying the group membership
role_ids = member.member_roles.reject(&:inherited?).collect(&:role_id)
next if role_ids.empty?
new_member.role_ids = role_ids
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 new_member.project = self
self.members << new_member
end
end
# Copies queries from +project+
def copy_queries(project)
project.queries.each do |query|
Jean-Philippe Lang
Time entry queries should be copied and deleted too....
r15938 new_query = query.class.new
Jean-Philippe Lang
Restores commits reverted when rails-4.1 branch was merged (#18174)....
r13122 new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria", "user_id", "type")
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 new_query.sort_criteria = query.sort_criteria if query.sort_criteria
new_query.project = self
Jean-Philippe Lang
Fixed: copied private queries not visible after project copy (#9520)....
r7662 new_query.user_id = query.user_id
Jean-Philippe Lang
Time entry queries should be copied and deleted too....
r15938 new_query.role_ids = query.role_ids if query.visibility == ::Query::VISIBILITY_ROLES
Jean-Philippe Lang
Project copy: let the user choose what to copy from the source project (everything by default)....
r2852 self.queries << new_query
end
end
Jean-Philippe Lang
Allow project forums copy....
r2862
# Copies boards from +project+
def copy_boards(project)
project.boards.each do |board|
new_board = Board.new
new_board.attributes = board.attributes.dup.except("id", "project_id", "topics_count", "messages_count", "last_message_id")
new_board.project = self
self.boards << new_board
end
end
Toshi MARUYAMA
remove trailing white-spaces from app/models/project.rb....
r6397
Jean-Philippe Lang
Added project module concept....
r714 def allowed_permissions
@allowed_permissions ||= begin
Jean-Philippe Lang
Avoid a query if enabled_modules association is already loaded (#15058)....
r11998 module_names = enabled_modules.loaded? ? enabled_modules.map(&:name) : enabled_modules.pluck(:name)
Jean-Philippe Lang
Added project module concept....
r714 Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name}
end
end
def allowed_actions
@actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
end
Eric Davis
Changed the Timelogs to use both the Systemwide and Project specific TimeEntryActivities...
r2834
Jean-Philippe Lang
Version sharing (#465) + optional inclusion of subprojects in the roadmap view (#2666)....
r3009 # Archives subprojects recursively
def archive!
children.each do |subproject|
subproject.send :archive!
end
update_attribute :status, STATUS_ARCHIVED
end
Jean-Philippe Lang
Initial commit...
r2 end