2011-02-27 13:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# Redmine - project management software  
						 
					
						
							
								
									
										
										
										
											2012-05-05 12:56:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# Copyright (C) 2006-2012  Jean-Philippe Lang  
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								#  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# 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.  
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								#  
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# 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.  
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								#  
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# 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  Issue  <  ActiveRecord :: Base  
						 
					
						
							
								
									
										
										
										
											2010-12-12 13:11:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  include  Redmine :: SafeAttributes 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  belongs_to  :project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :status ,  :class_name  = >  'IssueStatus' ,  :foreign_key  = >  'status_id' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :author ,  :class_name  = >  'User' ,  :foreign_key  = >  'author_id' 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-23 18:18:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  belongs_to  :assigned_to ,  :class_name  = >  'Principal' ,  :foreign_key  = >  'assigned_to_id' 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  belongs_to  :fixed_version ,  :class_name  = >  'Version' ,  :foreign_key  = >  'fixed_version_id' 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-30 23:30:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  belongs_to  :priority ,  :class_name  = >  'IssuePriority' ,  :foreign_key  = >  'priority_id' 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  belongs_to  :category ,  :class_name  = >  'IssueCategory' ,  :foreign_key  = >  'category_id' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  has_many  :journals ,  :as  = >  :journalized ,  :dependent  = >  :destroy 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  has_many  :visible_journals , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :class_name  = >  'Journal' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :as  = >  :journalized , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :conditions  = >  Proc . new  {  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [ " ( #{ Journal . table_name } .private_notes = ? OR ( #{ Project . allowed_to_condition ( User . current ,  :view_private_notes ) } )) " ,  false ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :readonly  = >  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-29 22:54:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  has_many  :time_entries ,  :dependent  = >  :delete_all 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-29 08:55:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  has_and_belongs_to_many  :changesets ,  :order  = >  " #{ Changeset . table_name } .committed_on ASC,  #{ Changeset . table_name } .id ASC " 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  has_many  :relations_from ,  :class_name  = >  'IssueRelation' ,  :foreign_key  = >  'issue_from_id' ,  :dependent  = >  :delete_all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  has_many  :relations_to ,  :class_name  = >  'IssueRelation' ,  :foreign_key  = >  'issue_to_id' ,  :dependent  = >  :delete_all 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-22 11:46:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_nested_set  :scope  = >  'root_id' ,  :dependent  = >  :destroy 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-24 09:34:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_attachable  :after_add  = >  :attachment_added ,  :after_remove  = >  :attachment_removed 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-27 20:13:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_customizable 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-21 12:08:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_watchable 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-20 17:26:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_searchable  :columns  = >  [ 'subject' ,  " #{ table_name } .description " ,  " #{ Journal . table_name } .notes " ] , 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                     :include  = >  [ :project ,  :visible_journals ] , 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-20 17:26:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                     # sort by id so that limited eager loading doesn't break with postgresql 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                     :order_column  = >  " #{ table_name } .id " 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-02 04:36:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_event  :title  = >  Proc . new  { | o |  " #{ o . tracker . name }   # #{ o . id }  ( #{ o . status } ):  #{ o . subject } " } , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-11 11:01:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                :url  = >  Proc . new  { | o |  { :controller  = >  'issues' ,  :action  = >  'show' ,  :id  = >  o . id } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                :type  = >  Proc . new  { | o |  'issue'  +  ( o . closed?  ?  ' closed'  :  '' )  } 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-30 11:18:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_activity_provider  :find_options  = >  { :include  = >  [ :project ,  :author ,  :tracker ] } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            :author_key  = >  :author_id 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-11 18:48:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DONE_RATIO_OPTIONS  =  %w( issue_field issue_status ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-04 16:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  attr_reader  :current_journal 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  delegate  :notes ,  :notes = ,  :private_notes ,  :private_notes = ,  :to  = >  :current_journal ,  :allow_nil  = >  true 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-10 05:10:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-07 19:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validates_presence_of  :subject ,  :priority ,  :project ,  :tracker ,  :author ,  :status 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-10 05:10:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-16 17:16:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validates_length_of  :subject ,  :maximum  = >  255 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validates_inclusion_of  :done_ratio ,  :in  = >  0 .. 100 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-15 14:54:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validates_numericality_of  :estimated_hours ,  :allow_nil  = >  true 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validate  :validate_issue ,  :validate_required_fields 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-26 23:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  scope  :visible , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lambda  { | * args |  {  :include  = >  :project , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                          :conditions  = >  Issue . visible_condition ( args . shift  ||  User . current ,  * args )  }  } 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-26 23:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  scope  :open ,  lambda  { | * args | 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-18 13:05:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    is_closed  =  args . size  >  0  ?  ! args . first  :  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { :conditions  = >  [ " #{ IssueStatus . table_name } .is_closed = ? " ,  is_closed ] ,  :include  = >  :status } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-11 18:48:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-26 23:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  scope  :recently_updated ,  :order  = >  " #{ Issue . table_name } .updated_on DESC " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  scope  :on_active_project ,  :include  = >  [ :status ,  :project ,  :tracker ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            :conditions  = >  [ " #{ Project . table_name } .status= #{ Project :: STATUS_ACTIVE } " ] 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-10 03:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-28 09:21:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  before_create  :default_assign 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-21 18:23:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  before_save  :close_duplicates ,  :update_done_ratio_from_issue_status ,  :force_updated_on_change 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  after_save  { | issue |  issue . send  :after_project_change  if  ! issue . id_changed?  &&  issue . project_id_changed? }  
							 
						 
					
						
							
								
									
										
										
										
											2010-10-19 19:16:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  after_save  :reschedule_following_issues ,  :update_nested_set_attributes ,  :update_parent_attributes ,  :create_journal 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Should be after_create but would be called before previous after_save callbacks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  after_save  :after_create_from_copy 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  after_destroy  :update_parent_attributes 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-15 16:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns a SQL conditions string used to find all issues visible by the specified user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . visible_condition ( user ,  options = { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-11 17:53:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Project . allowed_to_condition ( user ,  :view_issues ,  options )  do  | role ,  user | 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-20 19:26:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  user . logged? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  role . issues_visibility 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        when  'all' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        when  'default' 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-19 21:48:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          user_ids  =  [ user . id ]  +  user . groups . map ( & :id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " ( #{ table_name } .is_private =  #{ connection . quoted_false }  OR  #{ table_name } .author_id =  #{ user . id }  OR  #{ table_name } .assigned_to_id IN ( #{ user_ids . join ( ',' ) } )) " 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-20 19:26:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        when  'own' 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-19 21:48:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          user_ids  =  [ user . id ]  +  user . groups . map ( & :id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " ( #{ table_name } .author_id =  #{ user . id }  OR  #{ table_name } .assigned_to_id IN ( #{ user_ids . join ( ',' ) } )) " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          '1=0' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-11 17:53:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-20 19:26:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        " ( #{ table_name } .is_private =  #{ connection . quoted_false } ) " 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-11 17:53:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-15 16:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-31 13:22:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns true if usr or current user is allowed to view the issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  visible? ( usr = nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-11 17:53:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ( usr  ||  User . current ) . allowed_to? ( :view_issues ,  self . project )  do  | role ,  user | 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-20 19:26:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  user . logged? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  role . issues_visibility 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        when  'all' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        when  'default' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          ! self . is_private?  ||  ( self . author  ==  user  ||  user . is_or_belongs_to? ( assigned_to ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        when  'own' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          self . author  ==  user  ||  user . is_or_belongs_to? ( assigned_to ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-11 17:53:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-20 19:26:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ! self . is_private? 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-11 17:53:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-31 13:22:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-18 14:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  initialize ( attributes = nil ,  * args ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    super 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-05 17:44:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # set default values for new records only 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . status  || =  IssueStatus . default 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-30 23:30:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . priority  || =  IssuePriority . default 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 12:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . watcher_user_ids  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-05 17:44:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-06-18 17:16:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # AR#Persistence#destroy would raise and RecordNotFound exception 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # if the issue was already deleted or updated (non matching lock_version). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # This is a problem when bulk deleting issues or deleting a project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # (because an issue may already be deleted if its parent was deleted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # first). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # The issue is reloaded by the nested_set before being deleted so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # the lock_version condition should not be an issue but we handle it. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  destroy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    super 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  rescue  ActiveRecord :: RecordNotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Stale or already deleted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    begin 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      reload 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rescue  ActiveRecord :: RecordNotFound 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # The issue was actually already deleted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @destroyed  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  freeze 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # The issue was stale, retry to destroy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    super 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  reload ( * args ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @workflow_rule_by_attribute  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-27 19:36:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @assignable_versions  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    super 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-27 20:13:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  available_custom_fields 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-28 20:56:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ( project  &&  tracker )  ?  ( project . all_issue_custom_fields  &  tracker . custom_fields . all )  :  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-27 20:13:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:16:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Copies attributes from another issue, arg can be an id or an Issue 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-20 18:22:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  copy_from ( arg ,  options = { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 23:26:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    issue  =  arg . is_a? ( Issue )  ?  arg  :  Issue . visible . find ( arg ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . attributes  =  issue . attributes . dup . except ( " id " ,  " root_id " ,  " parent_id " ,  " lft " ,  " rgt " ,  " created_on " ,  " updated_on " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . custom_field_values  =  issue . custom_field_values . inject ( { } )  { | h , v |  h [ v . custom_field_id ]  =  v . value ;  h } 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-16 20:06:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . status  =  issue . status 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:06:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . author  =  User . current 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-20 18:22:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    unless  options [ :attachments ]  ==  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . attachments  =  issue . attachments . map  do  | attachement |  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        attachement . copy ( :container  = >  self ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-20 17:56:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:16:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @copied_from  =  issue 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @copy_options  =  options 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 14:31:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 18:02:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns an unsaved copy of the issue 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-14 06:21:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  copy ( attributes = nil ,  copy_options = { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    copy  =  self . class . new . copy_from ( self ,  copy_options ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 18:02:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    copy . attributes  =  attributes  if  attributes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    copy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:16:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns true if the issue is a copy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  copy? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @copied_from . present? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-25 13:12:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Moves/copies an issue to a new project and tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns the moved/copied issue on success, false on failure 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:46:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  move_to_project ( new_project ,  new_tracker = nil ,  options = { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 18:02:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ActiveSupport :: Deprecation . warn  " Issue # move_to_project is deprecated, use  # project= instead. " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-14 20:31:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  options [ :copy ] 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 18:02:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      issue  =  self . copy 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-14 20:31:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issue  =  self 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:34:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    issue . init_journal ( User . current ,  options [ :notes ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # Preserve previous behaviour 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # #move_to_project doesn't change tracker automatically 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    issue . send  :project = ,  new_project ,  true 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  new_tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issue . tracker  =  new_tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Allow bulk setting of attributes on the issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  options [ :attributes ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issue . attributes  =  options [ :attributes ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:34:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:46:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    issue . save  ?  issue  :  false 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-17 17:45:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-20 17:37:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  status_id = ( sid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . status  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    result  =  write_attribute ( :status_id ,  sid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @workflow_rule_by_attribute  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    result 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-20 17:37:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-05 17:44:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  priority_id = ( pid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . priority  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    write_attribute ( :priority_id ,  pid ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-29 19:46:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  category_id = ( cid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . category  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    write_attribute ( :category_id ,  cid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  fixed_version_id = ( vid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . fixed_version  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    write_attribute ( :fixed_version_id ,  vid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-29 19:46:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  tracker_id = ( tid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . tracker  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-09 09:12:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    result  =  write_attribute ( :tracker_id ,  tid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @custom_field_values  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @workflow_rule_by_attribute  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-09 09:12:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    result 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-29 19:46:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-21 08:46:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  project_id = ( project_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  project_id . to_s  !=  self . project_id . to_s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . project  =  ( project_id . present?  ?  Project . find_by_id ( project_id )  :  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  project = ( project ,  keep_tracker = false ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    project_was  =  self . project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    write_attribute ( :project_id ,  project  ?  project . id  :  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    association_instance_set ( 'project' ,  project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  project_was  &&  project  &&  project_was  !=  project 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-27 19:36:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @assignable_versions  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      unless  keep_tracker  ||  project . trackers . include? ( tracker ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . tracker  =  project . trackers . first 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # Reassign to the category with same name if any 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  category 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . category  =  project . issue_categories . find_by_name ( category . name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # Keep the fixed_version if it's still valid in the new_project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  fixed_version  &&  fixed_version . project  !=  project  &&  ! project . shared_versions . include? ( fixed_version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . fixed_version  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  parent  &&  parent . project_id  !=  project_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . parent_issue_id  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @custom_field_values  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 11:42:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  description = ( arg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  arg . is_a? ( String ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      arg  =  arg . gsub ( / ( \ r \ n| \ n| \ r) / ,  " \r \n " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    write_attribute ( :description ,  arg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-25 17:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Overrides assign_attributes so that project and tracker get assigned first 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  assign_attributes_with_project_and_tracker_first ( new_attributes ,  * args ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-09 09:12:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  if  new_attributes . nil? 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-08 20:37:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    attrs  =  new_attributes . dup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    attrs . stringify_keys! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    %w( project project_id tracker tracker_id ) . each  do  | attr | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  attrs . has_key? ( attr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        send  " #{ attr } = " ,  attrs . delete ( attr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-09 09:12:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-25 17:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    send  :assign_attributes_without_project_and_tracker_first ,  attrs ,  * args 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-09 09:12:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-14 12:43:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Do not redefine alias chain on reload (see #4838) 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-25 17:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  alias_method_chain ( :assign_attributes ,  :project_and_tracker_first )  unless  method_defined? ( :assign_attributes_without_project_and_tracker_first ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-26 11:59:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  estimated_hours = ( h ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    write_attribute  :estimated_hours ,  ( h . is_a? ( String )  ?  h . to_hours  :  h ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'project_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user | 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:16:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  issue . new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . copy? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elsif  user . allowed_to? ( :move_issues ,  issue . project ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:39:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        projects  =  Issue . allowed_target_projects_on_move ( user ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        projects . include? ( issue . project )  &&  projects . size  >  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-12-12 13:11:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'tracker_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'status_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'category_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'assigned_to_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'priority_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'fixed_version_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'subject' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'description' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'start_date' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'due_date' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'done_ratio' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'estimated_hours' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'custom_field_values' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'custom_fields' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'lock_version' , 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    'notes' , 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-12 13:11:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user |  issue . new_record?  ||  user . allowed_to? ( :edit_issues ,  issue . project )  } 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-12-12 13:11:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'status_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'assigned_to_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'fixed_version_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    'done_ratio' , 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-15 10:41:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    'lock_version' , 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    'notes' , 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-12 13:11:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user |  issue . new_statuses_allowed_to ( user ) . any?  } 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-11 16:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'notes' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user |  user . allowed_to? ( :add_issue_notes ,  issue . project ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  safe_attributes  'private_notes' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user |  ! issue . new_record?  &&  user . allowed_to? ( :set_notes_private ,  issue . project ) }  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-13 19:50:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'watcher_user_ids' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user |  issue . new_record?  &&  user . allowed_to? ( :add_issue_watchers ,  issue . project ) }  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 13:23:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'is_private' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      user . allowed_to? ( :set_issues_private ,  issue . project )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ( issue . author  ==  user  &&  user . allowed_to? ( :set_own_issues_private ,  issue . project ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-13 19:56:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'parent_issue_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user |  ( issue . new_record?  ||  user . allowed_to? ( :edit_issues ,  issue . project ) )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      user . allowed_to? ( :manage_subtasks ,  issue . project ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  safe_attribute_names ( user = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    names  =  super 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:20:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    names  -=  disabled_core_fields 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    names  -=  read_only_attribute_names ( user ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:20:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    names 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-12 20:17:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Safely sets attributes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Should be called from controllers instead of #attributes= 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # attr_accessible is too rough because we still want things like 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Issue.new(:project => foo) to work 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  safe_attributes = ( attrs ,  user = User . current ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-11 16:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  unless  attrs . is_a? ( Hash ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:20:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    attrs  =  attrs . dup 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # Project and Tracker must be set before since new_statuses_allowed_to depends on it. 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:20:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( p  =  attrs . delete ( 'project_id' ) )  &&  safe_attribute? ( 'project_id' ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  allowed_target_projects ( user ) . collect ( & :id ) . include? ( p . to_i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . project_id  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:20:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( t  =  attrs . delete ( 'tracker_id' ) )  &&  safe_attribute? ( 'tracker_id' ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-12 11:34:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . tracker_id  =  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( s  =  attrs . delete ( 'status_id' ) )  &&  safe_attribute? ( 'status_id' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  new_statuses_allowed_to ( user ) . collect ( & :id ) . include? ( s . to_i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . status_id  =  s 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 21:26:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    attrs  =  delete_unsafe_attributes ( attrs ,  user ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  if  attrs . empty? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    unless  leaf? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      attrs . reject!  { | k , v |  %w( priority_id done_ratio start_date due_date estimated_hours ) . include? ( k ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-13 19:56:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  attrs [ 'parent_issue_id' ] . present? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      attrs . delete ( 'parent_issue_id' )  unless  Issue . visible ( user ) . exists? ( attrs [ 'parent_issue_id' ] . to_i ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  attrs [ 'custom_field_values' ] . present? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      attrs [ 'custom_field_values' ]  =  attrs [ 'custom_field_values' ] . reject  { | k ,  v |  read_only_attribute_names ( user ) . include?  k . to_s } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  attrs [ 'custom_fields' ] . present? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      attrs [ 'custom_fields' ]  =  attrs [ 'custom_fields' ] . reject  { | c |  read_only_attribute_names ( user ) . include?  c [ 'id' ] . to_s } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-13 19:50:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # mass-assignment security bypass 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-25 17:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    assign_attributes  attrs ,  :without_protection  = >  true 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-12 20:17:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:20:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  disabled_core_fields 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tracker  ?  tracker . disabled_core_fields  :  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the custom_field_values that can be edited by the given user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  editable_custom_field_values ( user = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    custom_field_values . reject  do  | value | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      read_only_attribute_names ( user ) . include? ( value . custom_field_id . to_s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns the names of attributes that are read-only for user or the current user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # For users with multiple roles, the read-only fields are the intersection of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # read-only fields of each role 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # The result is an array of strings where sustom fields are represented with their ids 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Examples: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   issue.read_only_attribute_names # => ['due_date', '2'] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   issue.read_only_attribute_names(user) # => [] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  read_only_attribute_names ( user = nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:50:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    workflow_rule_by_attribute ( user ) . reject  { | attr ,  rule |  rule  !=  'readonly' } . keys 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns the names of required attributes for user or the current user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # For users with multiple roles, the required fields are the intersection of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # required fields of each role 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # The result is an array of strings where sustom fields are represented with their ids 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Examples: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   issue.required_attribute_names # => ['due_date', '2'] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   issue.required_attribute_names(user) # => [] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  required_attribute_names ( user = nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:50:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    workflow_rule_by_attribute ( user ) . reject  { | attr ,  rule |  rule  !=  'required' } . keys 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns true if the attribute is required for user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  required_attribute? ( name ,  user = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    required_attribute_names ( user ) . include? ( name . to_s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns a hash of the workflow rule by attribute for the given user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Examples: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   issue.workflow_rule_by_attribute # => {'due_date' => 'required', 'start_date' => 'readonly'} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  workflow_rule_by_attribute ( user = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  @workflow_rule_by_attribute  if  @workflow_rule_by_attribute  &&  user . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    user_real  =  user  ||  User . current 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    roles  =  user_real . admin  ?  Role . all  :  user_real . roles_for_project ( project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { }  if  roles . empty? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    result  =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    workflow_permissions  =  WorkflowPermission . where ( :tracker_id  = >  tracker_id ,  :old_status_id  = >  status_id ,  :role_id  = >  roles . map ( & :id ) ) . all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  workflow_permissions . any? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      workflow_rules  =  workflow_permissions . inject ( { } )  do  | h ,  wp | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        h [ wp . field_name ]  || =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        h [ wp . field_name ]  <<  wp . rule 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        h 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      workflow_rules . each  do  | attr ,  rules | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        next  if  rules . size  <  roles . size 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        uniq_rules  =  rules . uniq 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  uniq_rules . size  ==  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          result [ attr ]  =  uniq_rules . first 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          result [ attr ]  =  'required' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @workflow_rule_by_attribute  =  result  if  user . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  private  :workflow_rule_by_attribute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-11 18:48:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  done_ratio 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-26 18:13:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  Issue . use_status_for_done_ratio?  &&  status  &&  status . default_done_ratio 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-12 11:02:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      status . default_done_ratio 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-11 18:48:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      read_attribute ( :done_ratio ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . use_status_for_done_ratio? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Setting . issue_done_ratio  ==  'issue_status' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . use_field_for_done_ratio? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Setting . issue_done_ratio  ==  'issue_field' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-21 06:12:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  validate_issue 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  self . due_date . nil?  &&  @attributes [ 'due_date' ]  &&  ! @attributes [ 'due_date' ] . empty? 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-21 11:04:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      errors . add  :due_date ,  :not_a_date 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  self . due_date  and  self . start_date  and  self . due_date  <  self . start_date 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-21 11:04:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      errors . add  :due_date ,  :greater_than_start_date 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  start_date  &&  soonest_start  &&  start_date  <  soonest_start 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-21 11:04:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      errors . add  :start_date ,  :invalid 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 13:03:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  fixed_version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ! assignable_versions . include? ( fixed_version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        errors . add  :fixed_version_id ,  :inclusion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elsif  reopened?  &&  fixed_version . closed? 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-06 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        errors . add  :base ,  I18n . t ( :error_can_not_reopen_issue_on_closed_version ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 13:03:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-29 19:46:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # Checks that the issue can not be added/moved to a disabled tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  project  &&  ( tracker_id_changed?  ||  project_id_changed? ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      unless  project . trackers . include? ( tracker ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        errors . add  :tracker_id ,  :inclusion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # Checks parent issue assignment 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  @parent_issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  @parent_issue . project_id  !=  project_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        errors . add  :parent_issue_id ,  :not_same_project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elsif  ! new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # moving an existing issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  @parent_issue . root_id  !=  root_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          # we can always move to another tree 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elsif  move_possible? ( @parent_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          # move accepted inside tree 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          errors . add  :parent_issue_id ,  :not_a_valid_parent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Validates the issue against additional workflow requirements 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  validate_required_fields 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    user  =  new_record?  ?  author  :  current_journal . try ( :user ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    required_attribute_names ( user ) . each  do  | attribute | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  attribute  =~  / ^ \ d+$ / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        attribute  =  attribute . to_i 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        v  =  custom_field_values . detect  { | v |  v . custom_field_id  ==  attribute  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  v  &&  v . value . blank? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          errors . add  :base ,  v . custom_field . name  +  ' '  +  l ( 'activerecord.errors.messages.blank' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  respond_to? ( attribute )  &&  send ( attribute ) . blank? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          errors . add  attribute ,  :blank 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-11 18:48:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Set the done_ratio using the status if that setting is set.  This will keep the done_ratios 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # even if the user turns off the setting later 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  update_done_ratio_from_issue_status 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-26 18:13:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  Issue . use_status_for_done_ratio?  &&  status  &&  status . default_done_ratio 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-12 10:33:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . done_ratio  =  status . default_done_ratio 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-11 18:48:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  init_journal ( user ,  notes  =  " " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @current_journal  || =  Journal . new ( :journalized  = >  self ,  :user  = >  user ,  :notes  = >  notes ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:34:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @current_journal . notify  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @attributes_before_change  =  attributes . dup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @custom_values_before_change  =  { } 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 20:51:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . custom_field_values . each  { | c |  @custom_values_before_change . store  c . custom_field_id ,  c . value  } 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:34:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-04 17:36:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the id of the last journal or nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  last_journal_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 18:47:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      journals . maximum ( :id ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-04 17:36:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 21:28:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns a scope for journals that have an id greater than journal_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  journals_after ( journal_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    scope  =  journals . reorder ( " #{ Journal . table_name } .id ASC " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  journal_id . present? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      scope  =  scope . where ( " #{ Journal . table_name } .id > ? " ,  journal_id . to_i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    scope 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-25 17:45:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Return true if the issue is closed, otherwise false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . status . is_closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 13:03:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Return true if the issue is being reopened 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  reopened? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ! new_record?  &&  status_id_changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status_was  =  IssueStatus . find_by_id ( status_id_was ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status_new  =  IssueStatus . find_by_id ( status_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  status_was  &&  status_new  &&  status_was . is_closed?  &&  ! status_new . is_closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-28 09:21:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Return true if the issue is being closed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  closing? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ! new_record?  &&  status_id_changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status_was  =  IssueStatus . find_by_id ( status_id_was ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status_new  =  IssueStatus . find_by_id ( status_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  status_was  &&  status_new  &&  ! status_was . is_closed?  &&  status_new . is_closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-16 21:13:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns true if the issue is overdue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  overdue? 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-03 17:32:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ! due_date . nil?  &&  ( due_date  <  Date . today )  &&  ! status . is_closed? 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-16 21:13:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-10 03:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Is the amount of work done less than it should for the due date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  behind_schedule? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false  if  start_date . nil?  ||  due_date . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    done_date  =  start_date  +  ( ( due_date  -  start_date + 1 ) *  done_ratio / 100 ) . floor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  done_date  < =  Date . today 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 02:55:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Does this issue have children? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  children? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ! leaf? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-16 17:47:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Users the issue can be assigned to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  assignable_users 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-07 17:28:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    users  =  project . assignable_users 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    users  <<  author  if  author 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-23 19:24:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    users  <<  assigned_to  if  assigned_to 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-07 17:46:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    users . uniq . sort 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-16 17:47:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 13:03:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Versions that the issue can be assigned to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  assignable_versions 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-27 19:36:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  @assignable_versions  if  @assignable_versions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    versions  =  project . shared_versions . open . all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  fixed_version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  fixed_version_id_changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # nothing to do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elsif  project_id_changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  project . shared_versions . include? ( fixed_version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          versions  <<  fixed_version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        versions  <<  fixed_version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @assignable_versions  =  versions . uniq . sort 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 13:03:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-04 12:07:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns true if this issue is blocked by another issue that is still open 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  blocked? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ! relations_to . detect  { | ir |  ir . relation_type  ==  'blocks'  &&  ! ir . issue_from . closed? } . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-09 09:39:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns an array of statuses that user is able to apply 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-09 19:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  new_statuses_allowed_to ( user = User . current ,  include_default = false ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-14 05:45:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  new_record?  &&  @copied_from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [ IssueStatus . default ,  @copied_from . status ] . compact . uniq . sort 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      initial_status  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        initial_status  =  IssueStatus . default 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elsif  status_id_was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        initial_status  =  IssueStatus . find_by_id ( status_id_was ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      initial_status  || =  status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      statuses  =  initial_status . find_new_statuses_allowed_to ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        user . admin  ?  Role . all  :  user . roles_for_project ( project ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tracker , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        author  ==  user , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        assigned_to_id_changed?  ?  assigned_to_id_was  ==  user . id  :  assigned_to_id  ==  user . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      statuses  <<  initial_status  unless  statuses . empty? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      statuses  <<  IssueStatus . default  if  include_default 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      statuses  =  statuses . compact . uniq . sort 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      blocked?  ?  statuses . reject  { | s |  s . is_closed? }  :  statuses 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-06 17:06:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-23 17:55:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  assigned_to_was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  assigned_to_id_changed?  &&  assigned_to_id_was . present? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @assigned_to_was  || =  User . find_by_id ( assigned_to_id_was ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the users that should be notified 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  notified_users 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-23 17:55:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    notified  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-28 18:22:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # Author and assignee are always notified unless they have been 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # locked or don't want to be notified 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-23 17:55:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    notified  <<  author  if  author 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-23 18:18:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  assigned_to 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-23 17:55:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      notified  +=  ( assigned_to . is_a? ( Group )  ?  assigned_to . users  :  [ assigned_to ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  assigned_to_was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      notified  +=  ( assigned_to_was . is_a? ( Group )  ?  assigned_to_was . users  :  [ assigned_to_was ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-23 18:18:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-23 17:55:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    notified  =  notified . select  { | u |  u . active?  &&  u . notify_about? ( self ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    notified  +=  project . notified_users 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-03 21:28:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    notified . uniq! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Remove users that can not view the issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    notified . reject!  { | user |  ! visible? ( user ) } 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    notified 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns the email addresses that should be notified 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  recipients 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    notified_users . collect ( & :mail ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-03 21:28:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-04 16:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the number of hours spent on this issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  spent_hours 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @spent_hours  || =  time_entries . sum ( :hours )  ||  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the total number of hours spent on this issue and its descendants 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-21 00:39:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Example: 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  #   spent_hours => 0.0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   spent_hours => 50.2 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-04 16:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  total_spent_hours 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-18 08:21:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @total_spent_hours  || =  self_and_descendants . sum ( " #{ TimeEntry . table_name } .hours " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      :joins  = >  " LEFT JOIN  #{ TimeEntry . table_name }  ON  #{ TimeEntry . table_name } .issue_id =  #{ Issue . table_name } .id " ) . to_f  ||  0 . 0 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-23 12:22:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  relations 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-29 12:57:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @relations  || =  IssueRelations . new ( self ,  ( relations_from  +  relations_to ) . sort ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-24 15:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-21 08:46:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-24 15:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Preloads relations for a collection of issues 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . load_relations ( issues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  issues . any? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      relations  =  IssueRelation . all ( :conditions  = >  [ " issue_from_id IN (:ids) OR issue_to_id IN (:ids) " ,  { :ids  = >  issues . map ( & :id ) } ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issues . each  do  | issue | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . instance_variable_set  " @relations " ,  relations . select  { | r |  r . issue_from_id  ==  issue . id  ||  r . issue_to_id  ==  issue . id } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-21 08:46:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-04 16:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Preloads visible spent time for a collection of issues 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . load_visible_spent_hours ( issues ,  user = User . current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  issues . any? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      hours_by_issue_id  =  TimeEntry . visible ( user ) . sum ( :hours ,  :group  = >  :issue_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issues . each  do  | issue | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . instance_variable_set  " @spent_hours " ,  ( hours_by_issue_id [ issue . id ]  ||  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-29 12:57:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Preloads visible relations for a collection of issues 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . load_visible_relations ( issues ,  user = User . current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  issues . any? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issue_ids  =  issues . map ( & :id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # Relations with issue_from in given issues and visible issue_to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      relations_from  =  IssueRelation . includes ( :issue_to  = >  [ :status ,  :project ] ) . where ( visible_condition ( user ) ) . where ( :issue_from_id  = >  issue_ids ) . all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # Relations with issue_to in given issues and visible issue_from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      relations_to  =  IssueRelation . includes ( :issue_from  = >  [ :status ,  :project ] ) . where ( visible_condition ( user ) ) . where ( :issue_to_id  = >  issue_ids ) . all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issues . each  do  | issue | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        relations  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          relations_from . select  { | relation |  relation . issue_from_id  ==  issue . id }  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          relations_to . select  { | relation |  relation . issue_to_id  ==  issue . id } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . instance_variable_set  " @relations " ,  IssueRelations . new ( issue ,  relations . sort ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-04 17:03:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Finds an issue relation given its id. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  find_relation ( relation_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    IssueRelation . find ( relation_id ,  :conditions  = >  [ " issue_to_id = ? OR issue_from_id = ? " ,  id ,  id ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-13 13:00:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  all_dependent_issues ( except = [ ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    except  <<  self 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dependencies  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    relations_from . each  do  | relation | 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  relation . issue_to  &&  ! except . include? ( relation . issue_to ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-15 14:12:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dependencies  <<  relation . issue_to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dependencies  +=  relation . issue_to . all_dependent_issues ( except ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dependencies 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-03 18:30:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns an array of issues that duplicate this one 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-25 17:45:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  duplicates 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-03 18:30:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    relations_to . select  { | r |  r . relation_type  ==  IssueRelation :: TYPE_DUPLICATES } . collect  { | r |  r . issue_from } 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-25 17:45:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-25 13:26:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the due date or the target due date if any 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Used on gantt chart 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  due_before 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    due_date  ||  ( fixed_version  ?  fixed_version . effective_date  :  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-21 00:39:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the time scheduled for this issue. 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-21 00:39:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Example: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   Start Date: 2/26/09, End Date: 3/04/09 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   duration => 6 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( start_date  &&  due_date )  ?  due_date  -  start_date  :  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  soonest_start 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 15:29:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @soonest_start  || =  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        relations_to . collect { | relation |  relation . successor_soonest_start }  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ancestors . collect ( & :soonest_start ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ) . compact . max 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 15:29:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  reschedule_after ( date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  if  date . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  leaf? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  start_date . nil?  ||  start_date  <  date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . start_date ,  self . due_date  =  date ,  date  +  duration 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-12 19:41:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        begin 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        rescue  ActiveRecord :: StaleObjectError 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          reload 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          self . start_date ,  self . due_date  =  date ,  date  +  duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 15:29:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      leaves . each  do  | leaf | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        leaf . reschedule_after ( date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  <=> ( issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  issue . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      - 1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elsif  root_id  !=  issue . root_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ( root_id  ||  0 )  < = >  ( issue . root_id  ||  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ( lft  ||  0 )  < = >  ( issue . lft  ||  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-01 22:42:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  to_s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " #{ tracker }   # #{ id } :  #{ subject } " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-25 11:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns a string of css classes that apply to the issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  css_classes 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-26 16:55:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    s  =  " issue status- #{ status_id }  priority- #{ priority_id } " 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-25 11:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    s  <<  ' closed'  if  closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    s  <<  ' overdue'  if  overdue? 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-25 18:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    s  <<  ' child'  if  child? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    s  <<  ' parent'  unless  leaf? 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 13:23:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    s  <<  ' private'  if  is_private? 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-25 11:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    s  <<  ' created-by-me'  if  User . current . logged?  &&  author_id  ==  User . current . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    s  <<  ' assigned-to-me'  if  User . current . logged?  &&  assigned_to_id  ==  User . current . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-06 10:28:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-16 21:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Saves an issue and a time_entry from the parameters 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-05 17:11:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  save_issue_with_child_records ( params ,  existing_time_entry = nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-11 16:48:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Issue . transaction  do 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-13 16:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  params [ :time_entry ]  &&  ( params [ :time_entry ] [ :hours ] . present?  ||  params [ :time_entry ] [ :comments ] . present? )  &&  User . current . allowed_to? ( :log_time ,  project ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-11 16:48:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        @time_entry  =  existing_time_entry  ||  TimeEntry . new 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        @time_entry . project  =  project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        @time_entry . issue  =  self 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        @time_entry . user  =  User . current 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-24 20:39:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        @time_entry . spent_on  =  User . current . today 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-11 16:48:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        @time_entry . attributes  =  params [ :time_entry ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . time_entries  <<  @time_entry 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-16 21:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # TODO: Rename hook 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Redmine :: Hook . call_hook ( :controller_issues_edit_before_save ,  {  :params  = >  params ,  :issue  = >  self ,  :time_entry  = >  @time_entry ,  :journal  = >  @current_journal } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  save 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-11 16:48:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # TODO: Rename hook 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-16 21:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Redmine :: Hook . call_hook ( :controller_issues_edit_after_save ,  {  :params  = >  params ,  :issue  = >  self ,  :time_entry  = >  @time_entry ,  :journal  = >  @current_journal } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        raise  ActiveRecord :: Rollback 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-05 17:11:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-08 20:47:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Unassigns issues from +version+ if it's no longer shared with issue's project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . update_versions_from_sharing_change ( version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Update issues assigned to the version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    update_versions ( [ " #{ Issue . table_name } .fixed_version_id = ? " ,  version . id ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-08 20:47:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Unassigns issues from versions that are no longer shared 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # after +project+ was moved 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . update_versions_from_hierarchy_change ( project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    moved_project_ids  =  project . self_and_descendants . reload . collect ( & :id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Update issues of the moved projects and issues assigned to a version of a moved project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Issue . update_versions ( [ " #{ Version . table_name } .project_id IN (?) OR  #{ Issue . table_name } .project_id IN (?) " ,  moved_project_ids ,  moved_project_ids ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  parent_issue_id = ( arg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parent_issue_id  =  arg . blank?  ?  nil  :  arg . to_i 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  parent_issue_id  &&  @parent_issue  =  Issue . find_by_id ( parent_issue_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @parent_issue . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @parent_issue  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  parent_issue_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  instance_variable_defined?  :@parent_issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @parent_issue . nil?  ?  nil  :  @parent_issue . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      parent_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Extracted from the ReportsController. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_tracker ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :field  = >  'tracker_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :joins  = >  Tracker . table_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_version ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :field  = >  'fixed_version_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :joins  = >  Version . table_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_priority ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :field  = >  'priority_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :joins  = >  IssuePriority . table_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_category ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :field  = >  'category_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :joins  = >  IssueCategory . table_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_assigned_to ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :field  = >  'assigned_to_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :joins  = >  User . table_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_author ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :field  = >  'author_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       :joins  = >  User . table_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_subproject ( project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ActiveRecord :: Base . connection . select_all ( " select    s.id as status_id, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                s . is_closed  as  closed ,  
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 12:21:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                #{Issue.table_name}.project_id as project_id, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                count ( #{Issue.table_name}.id) as total  
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                              from  
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 12:21:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                #{Issue.table_name}, #{Project.table_name}, #{IssueStatus.table_name} s 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                              where  
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 12:21:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                #{Issue.table_name}.status_id=s.id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                and  #{Issue.table_name}.project_id = #{Project.table_name}.id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                and  #{visible_condition(User.current, :project => project, :with_subprojects => true)} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                and  #{Issue.table_name}.project_id <> #{project.id} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                              group  by  s . id ,  s . is_closed ,  #{Issue.table_name}.project_id") if project.descendants.active.any? 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # End ReportsController extraction 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns an array of projects that user can assign the issue to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  allowed_target_projects ( user = User . current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Project . all ( :conditions  = >  Project . allowed_to_condition ( user ,  :add_issues ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . class . allowed_target_projects_on_move ( user ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns an array of projects that user can move issues to 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  self . allowed_target_projects_on_move ( user = User . current ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-25 19:32:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Project . all ( :conditions  = >  Project . allowed_to_condition ( user ,  :move_issues ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-18 12:47:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-08 20:47:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  private 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  after_project_change 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Update project_id on related time entries 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TimeEntry . update_all ( [ " project_id = ? " ,  project_id ] ,  { :issue_id  = >  id } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Delete issue relations 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    unless  Setting . cross_project_issue_relations? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      relations_from . clear 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      relations_to . clear 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Move subtasks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    children . each  do  | child | 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-07 12:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # Change project and keep project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      child . send  :project = ,  project ,  true 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      unless  child . save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        raise  ActiveRecord :: Rollback 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-27 19:09:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Callback for after the creation of an issue by copy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * adds a "copied to" relation with the copied issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * copies subtasks from the copied issue 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  after_create_from_copy 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-27 19:09:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  unless  copy?  &&  ! @after_create_from_copy_handled 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-27 22:27:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( @copied_from . project_id  ==  project_id  ||  Setting . cross_project_issue_relations? )  &&  @copy_options [ :link ]  !=  false 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-27 19:09:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      relation  =  IssueRelation . new ( :issue_from  = >  @copied_from ,  :issue_to  = >  self ,  :relation_type  = >  IssueRelation :: TYPE_COPIED_TO ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      unless  relation . save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        logger . error  " Could not create relation while copying  # #{ @copied_from . id }  to  # #{ id }  due to validation errors:  #{ relation . errors . full_messages . join ( ', ' ) } "  if  logger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    unless  @copied_from . leaf?  ||  @copy_options [ :subtasks ]  ==  false 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @copied_from . children . each  do  | child | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        unless  child . visible? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          # Do not copy subtasks that are not visible to avoid potential disclosure of private data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          logger . error  " Subtask  # #{ child . id }  was not copied during  # #{ @copied_from . id }  copy because it is not visible to the current user "  if  logger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          next 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        copy  =  Issue . new . copy_from ( child ,  @copy_options ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        copy . author  =  author 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        copy . project  =  project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        copy . parent_issue_id  =  id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Children subtasks are copied recursively 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        unless  copy . save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          logger . error  " Could not copy subtask  # #{ child . id }  while copying  # #{ @copied_from . id }  to  # #{ id }  due to validation errors:  #{ copy . errors . full_messages . join ( ', ' ) } "  if  logger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-27 19:09:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @after_create_from_copy_handled  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  update_nested_set_attributes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  root_id . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # issue was just created 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . root_id  =  ( @parent_issue . nil?  ?  id  :  @parent_issue . root_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_default_left_and_right 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Issue . update_all ( " root_id =  #{ root_id } , lft =  #{ lft } , rgt =  #{ rgt } " ,  [ " id = ? " ,  id ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  @parent_issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        move_to_child_of ( @parent_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      reload 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elsif  parent_issue_id  !=  parent_id 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-30 02:45:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      former_parent_id  =  parent_id 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # moving an existing issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  @parent_issue  &&  @parent_issue . root_id  ==  root_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # inside the same tree 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        move_to_child_of ( @parent_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # to another tree 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        unless  root? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          move_to_right_of ( root ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          reload 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        old_root_id  =  root_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . root_id  =  ( @parent_issue . nil?  ?  id  :  @parent_issue . root_id  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        target_maxright  =  nested_set_scope . maximum ( right_column_name )  ||  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        offset  =  target_maxright  +  1  -  lft 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Issue . update_all ( " root_id =  #{ root_id } , lft = lft +  #{ offset } , rgt = rgt +  #{ offset } " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                          [ " root_id = ? AND lft >= ? AND rgt <= ?  " ,  old_root_id ,  lft ,  rgt ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self [ left_column_name ]  =  lft  +  offset 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self [ right_column_name ]  =  rgt  +  offset 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  @parent_issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          move_to_child_of ( @parent_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      reload 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # delete invalid relations of all descendants 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self_and_descendants . each  do  | issue | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . relations . each  do  | relation | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          relation . destroy  unless  relation . valid? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-30 02:45:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # update former parent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      recalculate_attributes_for ( former_parent_id )  if  former_parent_id 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    remove_instance_variable ( :@parent_issue )  if  instance_variable_defined? ( :@parent_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  update_parent_attributes 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-30 02:45:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    recalculate_attributes_for ( parent_id )  if  parent_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  recalculate_attributes_for ( issue_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  issue_id  &&  p  =  Issue . find_by_id ( issue_id ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # priority = highest priority of children 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-26 12:07:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  priority_position  =  p . children . maximum ( " #{ IssuePriority . table_name } .position " ,  :joins  = >  :priority ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        p . priority  =  IssuePriority . find_by_position ( priority_position ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # start/due dates = lowest/highest dates of children 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p . start_date  =  p . children . minimum ( :start_date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p . due_date  =  p . children . maximum ( :due_date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  p . start_date  &&  p . due_date  &&  p . due_date  <  p . start_date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p . start_date ,  p . due_date  =  p . due_date ,  p . start_date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # done ratio = weighted average ratio of leaves 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-26 18:13:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      unless  Issue . use_status_for_done_ratio?  &&  p . status  &&  p . status . default_done_ratio 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        leaves_count  =  p . leaves . count 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  leaves_count  >  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          average  =  p . leaves . average ( :estimated_hours ) . to_f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  average  ==  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            average  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          end 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-26 12:07:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          done  =  p . leaves . sum ( " COALESCE(estimated_hours,  #{ average } ) * (CASE WHEN is_closed =  #{ connection . quoted_true }  THEN 100 ELSE COALESCE(done_ratio, 0) END) " ,  :joins  = >  :status ) . to_f 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          progress  =  done  /  ( average  *  leaves_count ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          p . done_ratio  =  progress . round 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # estimate = sum of leaves estimates 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p . estimated_hours  =  p . leaves . sum ( :estimated_hours ) . to_f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p . estimated_hours  =  nil  if  p . estimated_hours  ==  0 . 0 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # ancestors will be recursively updated 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-25 17:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      p . save ( :validate  = >  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-08 20:47:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Update issues so their versions are not pointing to a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # fixed_version that is not shared with the issue's project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . update_versions ( conditions = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Only need to update issues with a fixed_version from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # a different project and that is not systemwide shared 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-18 15:02:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Issue . scoped ( :conditions  = >  conditions ) . all ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      :conditions  = >  " #{ Issue . table_name } .fixed_version_id IS NOT NULL "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "  AND  #{ Issue . table_name } .project_id <>  #{ Version . table_name } .project_id "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "  AND  #{ Version . table_name } .sharing <> 'system' " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      :include  = >  [ :project ,  :fixed_version ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) . each  do  | issue | 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-06 10:28:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      next  if  issue . project . nil?  ||  issue . fixed_version . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      unless  issue . project . shared_versions . include? ( issue . fixed_version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . init_journal ( User . current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . fixed_version  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-21 08:46:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-12 21:30:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Callback on file attachment 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-24 09:34:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  attachment_added ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  @current_journal  &&  ! obj . new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @current_journal . details  <<  JournalDetail . new ( :property  = >  'attachment' ,  :prop_key  = >  obj . id ,  :value  = >  obj . filename ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 16:54:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Callback on attachment deletion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  attachment_removed ( obj ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-04 11:41:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  @current_journal  &&  ! obj . new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @current_journal . details  <<  JournalDetail . new ( :property  = >  'attachment' ,  :prop_key  = >  obj . id ,  :old_value  = >  obj . filename ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @current_journal . save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 16:54:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-28 09:21:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Default assignment based on category 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  default_assign 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  assigned_to . nil?  &&  category  &&  category . assigned_to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assigned_to  =  category . assigned_to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Updates start/due dates of following issues 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  reschedule_following_issues 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  start_date_changed?  ||  due_date_changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      relations_from . each  do  | relation | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        relation . set_issue_to_dates 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Closes duplicates if the issue is being closed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  close_duplicates 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  closing? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      duplicates . each  do  | duplicate | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Reload is need in case the duplicate was updated by a previous duplicate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        duplicate . reload 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Don't re-close it if it's already closed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        next  if  duplicate . closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Same user and notes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  @current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          duplicate . init_journal ( @current_journal . user ,  @current_journal . notes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        duplicate . update_attribute  :status ,  self . status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-21 18:23:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Make sure updated_on is updated when adding a note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  force_updated_on_change 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  @current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . updated_on  =  current_time_from_proper_timezone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 19:11:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Saves the changes in a Journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Called after_save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  create_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  @current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # attributes changes 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:34:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  @attributes_before_change 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ( Issue . column_names  -  %w( id root_id lft rgt lock_version created_on updated_on ) ) . each  { | c | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          before  =  @attributes_before_change [ c ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          after  =  send ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          next  if  before  ==  after  ||  ( before . blank?  &&  after . blank? ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          @current_journal . details  <<  JournalDetail . new ( :property  = >  'attr' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                        :prop_key  = >  c , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                        :old_value  = >  before , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                        :value  = >  after ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  @custom_values_before_change 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # custom fields changes 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 20:51:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        custom_field_values . each  { | c | 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:34:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          before  =  @custom_values_before_change [ c . custom_field_id ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          after  =  c . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          next  if  before  ==  after  ||  ( before . blank?  &&  after . blank? ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-29 20:51:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  before . is_a? ( Array )  ||  after . is_a? ( Array ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            before  =  [ before ]  unless  before . is_a? ( Array ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            after  =  [ after ]  unless  after . is_a? ( Array ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # values removed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( before  -  after ) . reject ( & :blank? ) . each  do  | value | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              @current_journal . details  <<  JournalDetail . new ( :property  = >  'cf' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                            :prop_key  = >  c . custom_field_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                            :old_value  = >  value , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                            :value  = >  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # values added 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( after  -  before ) . reject ( & :blank? ) . each  do  | value | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              @current_journal . details  <<  JournalDetail . new ( :property  = >  'cf' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                            :prop_key  = >  c . custom_field_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                            :old_value  = >  nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                            :value  = >  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            @current_journal . details  <<  JournalDetail . new ( :property  = >  'cf' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                          :prop_key  = >  c . custom_field_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                          :old_value  = >  before , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                          :value  = >  after ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          end 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 20:34:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 19:11:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @current_journal . save 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-28 09:21:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # reset current journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      init_journal  @current_journal . user ,  @current_journal . notes 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 19:11:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Query generator for selecting groups of issue counts for a project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # based on specific criteria 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * project - Project to search in. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * field - String. Issue field to key off of in the grouping. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * joins - String. The table name to join against. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . count_and_group_by ( options ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    project  =  options . delete ( :project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    select_field  =  options . delete ( :field ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    joins  =  options . delete ( :joins ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 12:21:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    where  =  " #{ Issue . table_name } . #{ select_field } =j.id " 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ActiveRecord :: Base . connection . select_all ( " select    s.id as status_id, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                s . is_closed  as  closed ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                j . id  as  #{select_field}, 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 12:21:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                count ( #{Issue.table_name}.id) as total  
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                              from  
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 12:21:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                  #{Issue.table_name}, #{Project.table_name}, #{IssueStatus.table_name} s, #{joins} j 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                              where  
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 12:21:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                #{Issue.table_name}.status_id=s.id  
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                and  #{where} 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 12:21:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                and  #{Issue.table_name}.project_id=#{Project.table_name}.id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                and  #{visible_condition(User.current, :project => project)} 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                              group  by  s . id ,  s . is_closed ,  j . id " )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-28 18:11:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								end