2007-03-12 20:59:02 +03:00
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# 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.
#
# 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.
#
# 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
2007-05-27 21:42:04 +04:00
# Project statuses
STATUS_ACTIVE = 1
STATUS_ARCHIVED = 9
2007-03-16 01:11:02 +03:00
has_many :members , :dependent = > :delete_all , :include = > :user , :conditions = > " #{ User . table_name } .status= #{ User :: STATUS_ACTIVE } "
2007-03-12 20:59:02 +03:00
has_many :users , :through = > :members
has_many :custom_values , :dependent = > :delete_all , :as = > :customized
2007-03-16 01:11:02 +03:00
has_many :issues , :dependent = > :destroy , :order = > " #{ Issue . table_name } .created_on DESC " , :include = > [ :status , :tracker ]
2007-08-16 14:38:23 +04:00
has_many :issue_changes , :through = > :issues , :source = > :journals
2007-06-25 23:17:58 +04:00
has_many :versions , :dependent = > :destroy , :order = > " #{ Version . table_name } .effective_date DESC, #{ Version . table_name } .name DESC "
2007-03-23 15:22:31 +03:00
has_many :time_entries , :dependent = > :delete_all
2007-03-12 20:59:02 +03:00
has_many :queries , :dependent = > :delete_all
has_many :documents , :dependent = > :destroy
has_many :news , :dependent = > :delete_all , :include = > :author
2007-03-16 01:11:02 +03:00
has_many :issue_categories , :dependent = > :delete_all , :order = > " #{ IssueCategory . table_name } .name "
2007-05-13 21:09:56 +04:00
has_many :boards , :order = > " position ASC "
2007-03-12 20:59:02 +03:00
has_one :repository , :dependent = > :destroy
has_one :wiki , :dependent = > :destroy
2007-03-16 01:11:02 +03:00
has_and_belongs_to_many :custom_fields , :class_name = > 'IssueCustomField' , :join_table = > " #{ table_name_prefix } custom_fields_projects #{ table_name_suffix } " , :association_foreign_key = > 'custom_field_id'
2007-03-12 20:59:02 +03:00
acts_as_tree :order = > " name " , :counter_cache = > true
2007-04-01 23:43:59 +04:00
2007-05-27 21:42:04 +04:00
attr_protected :status
2007-04-01 23:43:59 +04:00
validates_presence_of :name , :description , :identifier
validates_uniqueness_of :name , :identifier
2007-03-12 20:59:02 +03:00
validates_associated :custom_values , :on = > :update
validates_associated :repository , :wiki
2007-04-02 22:44:35 +04:00
validates_length_of :name , :maximum = > 30
2007-03-12 20:59:02 +03:00
validates_format_of :name , :with = > / ^[ \ w \ s \ ' \ -]*$ /i
2007-04-02 22:44:35 +04:00
validates_length_of :description , :maximum = > 255
validates_length_of :identifier , :in = > 3 .. 12
2007-04-01 23:43:59 +04:00
validates_format_of :identifier , :with = > / ^[a-z0-9 \ -]*$ /
def identifier = ( identifier )
super unless identifier_frozen?
end
def identifier_frozen?
errors [ :identifier ] . nil? && ! ( new_record? || identifier . blank? )
end
2007-04-02 21:12:02 +04:00
def issues_with_subprojects ( include_subprojects = false )
conditions = nil
2007-05-27 21:42:04 +04:00
if include_subprojects && ! active_children . empty?
ids = [ id ] + active_children . collect { | c | c . id }
2007-04-02 21:12:02 +04:00
conditions = [ " #{ Issue . table_name } .project_id IN ( #{ ids . join ( ',' ) } ) " ]
end
2007-05-27 21:42:04 +04:00
conditions || = [ " #{ Issue . table_name } .project_id = ? " , id ]
2007-04-02 21:12:02 +04:00
Issue . with_scope :find = > { :conditions = > conditions } do
yield
end
end
2007-03-12 20:59:02 +03:00
# 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 )
2007-03-16 01:11:02 +03:00
find ( :all , :limit = > count , :conditions = > visible_by ( user ) , :order = > " created_on DESC " )
2007-03-12 20:59:02 +03:00
end
def self . visible_by ( user = nil )
2007-04-21 20:40:56 +04:00
if user && user . admin?
2007-05-27 21:42:04 +04:00
return [ " #{ Project . table_name } .status= #{ Project :: STATUS_ACTIVE } " ]
2007-06-23 20:36:01 +04:00
elsif user && user . memberships . any?
2007-05-27 21:42:04 +04:00
return [ " #{ Project . table_name } .status= #{ Project :: STATUS_ACTIVE } AND ( #{ Project . table_name } .is_public = ? or #{ Project . table_name } .id IN ( #{ user . memberships . collect { | m | m . project_id } . join ( ',' ) } )) " , true ]
2007-03-12 20:59:02 +03:00
else
2007-05-27 21:42:04 +04:00
return [ " #{ Project . table_name } .status= #{ Project :: STATUS_ACTIVE } AND #{ Project . table_name } .is_public = ? " , true ]
end
end
def active?
self . status == STATUS_ACTIVE
end
def archive
# Archive subprojects if any
children . each do | subproject |
subproject . archive
2007-03-12 20:59:02 +03:00
end
2007-05-27 21:42:04 +04:00
update_attribute :status , STATUS_ARCHIVED
end
def unarchive
return false if parent && ! parent . active?
update_attribute :status , STATUS_ACTIVE
end
def active_children
children . select { | child | child . active? }
2007-03-12 20:59:02 +03:00
end
# Returns an array of all custom fields enabled for project issues
# (explictly associated custom fields and custom fields enabled for all projects)
def custom_fields_for_issues ( tracker )
2007-03-16 01:11:02 +03:00
all_custom_fields . select { | c | tracker . custom_fields . include? c }
2007-03-12 20:59:02 +03:00
end
def all_custom_fields
2007-03-16 01:11:02 +03:00
@all_custom_fields || = ( IssueCustomField . for_all + custom_fields ) . uniq
2007-03-12 20:59:02 +03:00
end
protected
def validate
errors . add ( parent_id , " must be a root project " ) if parent and parent . parent
errors . add_to_base ( " A project with subprojects can't be a subproject " ) if parent and children . size > 0
2006-07-09 20:30:01 +04:00
end
2006-06-28 22:11:03 +04:00
end