2011-02-27 13:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# Redmine - project management software  
						 
					
						
							
								
									
										
										
										
											2015-01-11 09:09:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# Copyright (C) 2006-2015  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 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-29 10:06:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  include  Redmine :: Utils :: DateCalculation 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-04 17:17:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  include  Redmine :: I18n 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-07 20:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  before_save  :set_parent_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  include  Redmine :: NestedSet :: IssueNestedSet 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  belongs_to  :project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :tracker 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 18:41:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  belongs_to  :status ,  :class_name  = >  'IssueStatus' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :author ,  :class_name  = >  'User' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :assigned_to ,  :class_name  = >  'Principal' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :fixed_version ,  :class_name  = >  'Version' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :priority ,  :class_name  = >  'IssuePriority' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  belongs_to  :category ,  :class_name  = >  'IssueCategory' 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-01-21 08:27:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  has_many  :journals ,  :as  = >  :journalized ,  :dependent  = >  :destroy ,  :inverse_of  = >  :journalized 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  has_many  :visible_journals , 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lambda  { where ( [ " ( #{ Journal . table_name } .private_notes = ? OR ( #{ Project . allowed_to_condition ( User . current ,  :view_private_notes ) } )) " ,  false ] ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :class_name  = >  'Journal' , 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :as  = >  :journalized 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 18:39:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  has_many  :time_entries ,  :dependent  = >  :destroy 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  has_and_belongs_to_many  :changesets ,  lambda  { 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-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 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-08 22:04:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_searchable  :columns  = >  [ 'subject' ,  " #{ table_name } .description " ] , 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-10 10:09:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                     :preload  = >  [ :project ,  :status ,  :tracker ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                     :scope  = >  lambda  { | options |  options [ :open_issues ]  ?  self . open  :  self . all } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  acts_as_activity_provider  :scope  = >  preload ( :project ,  :author ,  :tracker ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-30 11:18:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            :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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-06 11:23:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validates_presence_of  :subject ,  :project ,  :tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  validates_presence_of  :priority ,  :if  = >  Proc . new  { | issue |  issue . new_record?  ||  issue . priority_id_changed? } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  validates_presence_of  :status ,  :if  = >  Proc . new  { | issue |  issue . new_record?  ||  issue . status_id_changed? } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  validates_presence_of  :author ,  :if  = >  Proc . new  { | issue |  issue . new_record?  ||  issue . author_id_changed? } 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-05 16:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validates  :estimated_hours ,  :numericality  = >  { :greater_than_or_equal_to  = >  0 ,  :allow_nil  = >  true ,  :message  = >  :invalid } 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-05 16:09:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validates  :start_date ,  :date  = >  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  validates  :due_date ,  :date  = >  true 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  validate  :validate_issue ,  :validate_required_fields 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  attr_protected  :id 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 17:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-07 17:59:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  scope  :visible ,  lambda  { | * args | 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-17 17:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    joins ( :project ) . 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    where ( Issue . visible_condition ( args . shift  ||  User . current ,  * args ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-07 17:59:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    joins ( :status ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    where ( " #{ IssueStatus . table_name } .is_closed = ? " ,  is_closed ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-18 13:05:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-11 18:48:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-07 17:59:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  scope  :recently_updated ,  lambda  {  order ( " #{ Issue . table_name } .updated_on DESC " )  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  scope  :on_active_project ,  lambda  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    joins ( :project ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    where ( " #{ Project . table_name } .status = ? " ,  Project :: STATUS_ACTIVE ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-07 17:59:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-06 14:03:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  scope  :fixed_version ,  lambda  { | versions | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ids  =  [ versions ] . flatten . compact . map  { | v |  v . is_a? ( Version )  ?  v . id  :  v } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ids . any?  ?  where ( :fixed_version_id  = >  ids )  :  where ( '1=0' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-10 03:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-14 17:16:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  before_validation  :clear_disabled_fields 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-28 09:21:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  before_create  :default_assign 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-24 05:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  before_save  :close_duplicates ,  :update_done_ratio_from_issue_status , 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-17 20:48:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              :force_updated_on_change ,  :update_closed_on ,  :set_assigned_to_was 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-08 11:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  after_save  { | issue |  issue . send  :after_project_change  if  ! issue . id_changed?  &&  issue . project_id_changed? } 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-24 05:40:21 +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 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-14 14:26:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  after_create  :send_notification 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-17 20:48:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Keep it at the end of after_save callbacks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  after_save  :clear_assigned_to_was 
							 
						 
					
						
							
								
									
										
										
										
											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 | 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  user . id  &&  user . logged? 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-20 19:26:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  role . issues_visibility 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        when  'all' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        when  'default' 
							 
						 
					
						
							
								
									
										
										
										
											2013-09-25 17:35:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          user_ids  =  [ user . id ]  +  user . groups . map ( & :id ) . compact 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-19 21:48:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          " ( #{ 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' 
							 
						 
					
						
							
								
									
										
										
										
											2013-09-25 17:35:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          user_ids  =  [ user . id ]  +  user . groups . map ( & :id ) . compact 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-19 21:48:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          " ( #{ 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-22 10:30:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns true if user or current user is allowed to edit or add a note to the issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  editable? ( user = User . current ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-13 19:30:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    attributes_editable? ( user )  ||  user . allowed_to? ( :add_issue_notes ,  project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns true if user or current user is allowed to edit the issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  attributes_editable? ( user = User . current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    user . allowed_to? ( :edit_issues ,  project ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-22 10:30:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-17 09:30:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  create_or_update 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    super 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ensure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @status_was  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  private  :create_or_update 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-07 20:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  rescue  ActiveRecord :: StaleObjectError ,  ActiveRecord :: RecordNotFound 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-18 17:16:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # 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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-28 18:47:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  alias  :base_reload  :reload 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-24 09:59:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @relations  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-22 09:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @spent_hours  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 12:09:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @total_spent_hours  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 11:37:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @total_estimated_hours  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-28 18:47:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    base_reload ( * args ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-27 20:13:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  available_custom_fields 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-22 11:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ( project  &&  tracker )  ?  ( project . all_issue_custom_fields  &  tracker . custom_fields )  :  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-27 20:13:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-07-13 09:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  visible_custom_field_values ( user = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    user_real  =  user  ||  User . current 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    custom_field_values . select  do  | value | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      value . custom_field . visible_by? ( project ,  user_real ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-08 11:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . attachments  =  issue . attachments . map  do  | attachement | 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-20 18:22:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  status_id = ( status_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  status_id . to_s  !=  self . status_id . to_s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . status  =  ( status_id . present?  ?  IssueStatus . find_by_id ( status_id )  :  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . status_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Sets the status. 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 09:05:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  status = ( status ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  status  !=  self . status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @workflow_rule_by_attribute  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    association ( :status ) . writer ( status ) 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 14:44:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  tracker_id = ( tracker_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  tracker_id . to_s  !=  self . tracker_id . to_s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . tracker  =  ( tracker_id . present?  ?  Tracker . find_by_id ( tracker_id )  :  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . tracker_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Sets the tracker. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # This will set the status to the default status of the new tracker if: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * the status was the default for the previous tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * or if the status was not part of the new tracker statuses 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * or the status was nil 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 14:44:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  tracker = ( tracker ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-16 05:10:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  tracker  !=  self . tracker 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  status  ==  default_status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . status  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elsif  status  &&  tracker  &&  ! tracker . issue_status_ids . include? ( status . id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . status  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 14:44:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @custom_field_values  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @workflow_rule_by_attribute  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    association ( :tracker ) . writer ( tracker ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . status  || =  default_status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . tracker 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 14:44:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . project_id 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Sets the project. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Unless keep_tracker argument is set to true, this will change the tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # to the first tracker of the new project if the previous tracker is not part 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # of the new project trackers. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # This will clear the fixed_version is it's no longer valid for the new project. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # This will clear the parent issue if it's no longer valid for the new project. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # This will set the category to the category with the same name in the new 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # project if it exists, or clear it if it doesn't. 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 14:44:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    association ( :project ) . writer ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-10 17:38:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # Clear the parent task if it's no longer valid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      unless  valid_parent_project? 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . parent_issue_id  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @custom_field_values  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @workflow_rule_by_attribute  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . project 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  attributes = ( new_attributes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assign_attributes  new_attributes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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' , 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-14 08:03:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    'tracker_id' , 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-12 13:11:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    '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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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' , 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-08 11:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user |  ! issue . new_record?  &&  user . allowed_to? ( :set_notes_private ,  issue . project ) } 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-03 21:36:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-13 19:50:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'watcher_user_ids' , 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-08 11:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user |  issue . new_record?  &&  user . allowed_to? ( :add_issue_watchers ,  issue . project ) } 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-13 19:50:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 13:23:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  safe_attributes  'is_private' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :if  = >  lambda  { | issue ,  user | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      user . allowed_to? ( :set_issues_private ,  issue . project )  || 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-08 11:09:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ( issue . author_id  ==  user . id  &&  user . allowed_to? ( :set_own_issues_private ,  issue . project ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 13:23:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-14 08:03:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  new_record? 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-21 16:38:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # Make sure that project_id can always be set for new issues 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-08 12:07:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      names  |=  %w( project_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 09:53:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  dates_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      names  -=  %w( start_date due_date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  priority_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      names  -=  %w( priority_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 10:03:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  done_ratio_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      names  -=  %w( done_ratio ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    attrs  =  attrs . deep_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' ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-11 16:54:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  allowed_target_projects ( user ) . where ( :id  = >  p . to_i ) . exists? 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . project_id  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-20 18:57:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  project_id_changed?  &&  attrs [ 'category_id' ] . to_s  ==  category_id_was . to_s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Discard submitted category on previous project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        attrs . delete ( 'category_id' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      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 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-14 09:53:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # Set the default tracker to accept custom field values 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # even if tracker is not specified 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . tracker  || =  project . trackers . first 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-26 08:30:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    statuses_allowed  =  new_statuses_allowed_to ( user ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( s  =  attrs . delete ( 'status_id' ) )  &&  safe_attribute? ( 'status_id' ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-26 08:30:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  statuses_allowed . collect ( & :id ) . include? ( s . to_i ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . status_id  =  s 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 21:26:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-26 08:30:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  new_record?  &&  ! statuses_allowed . include? ( status ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . status  =  statuses_allowed . first  ||  default_status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    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? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-13 19:56:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  attrs [ 'parent_issue_id' ] . present? 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-14 14:35:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      s  =  attrs [ 'parent_issue_id' ] . to_s 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-20 16:41:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      unless  ( m  =  s . match ( %r{ \ A # ?( \ d+) \ z } ) )  &&  ( m [ 1 ]  ==  parent_id . to_s  ||  Issue . visible ( user ) . exists? ( m [ 1 ] ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-12 13:40:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        @invalid_parent_issue_id  =  attrs . delete ( 'parent_issue_id' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											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? 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-13 09:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      editable_custom_field_ids  =  editable_custom_field_values ( user ) . map  { | v |  v . custom_field_id . to_s } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      attrs [ 'custom_field_values' ] . select!  { | k ,  v |  editable_custom_field_ids . include? ( k . to_s ) } 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  attrs [ 'custom_fields' ] . present? 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-13 09:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      editable_custom_field_ids  =  editable_custom_field_values ( user ) . map  { | v |  v . custom_field_id . to_s } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      attrs [ 'custom_fields' ] . select!  { | c |  editable_custom_field_ids . include? ( c [ 'id' ] . to_s ) } 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-13 09:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    visible_custom_field_values ( user ) . reject  do  | value | 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      read_only_attribute_names ( user ) . include? ( value . custom_field_id . to_s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-05-02 07:32:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the custom fields that can be edited by the given user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  editable_custom_fields ( user = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    editable_custom_field_values ( user ) . map ( & :custom_field ) . uniq 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # 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 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 22:20:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    roles  =  user_real . admin  ?  Role . all . to_a  :  user_real . roles_for_project ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-13 14:31:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    roles  =  roles . select ( & :consider_workflow? ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { }  if  roles . empty? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    result  =  { } 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 22:20:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    workflow_permissions  =  WorkflowPermission . where ( :tracker_id  = >  tracker_id ,  :old_status_id  = >  status_id ,  :role_id  = >  roles . map ( & :id ) ) . to_a 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  workflow_permissions . any? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      workflow_rules  =  workflow_permissions . inject ( { } )  do  | h ,  wp | 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-20 09:17:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        h [ wp . field_name ]  || =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        h [ wp . field_name ] [ wp . role_id ]  =  wp . rule 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        h 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-20 09:17:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      fields_with_roles  =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      IssueCustomField . where ( :visible  = >  false ) . joins ( :roles ) . pluck ( :id ,  " role_id " ) . each  do  | field_id ,  role_id | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        fields_with_roles [ field_id ]  || =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        fields_with_roles [ field_id ]  <<  role_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      roles . each  do  | role | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        fields_with_roles . each  do  | field_id ,  role_ids | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          unless  role_ids . include? ( role . id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            field_name  =  field_id . to_s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            workflow_rules [ field_name ]  || =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            workflow_rules [ field_name ] [ role . id ]  =  'readonly' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      workflow_rules . each  do  | attr ,  rules | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        next  if  rules . size  <  roles . size 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-20 09:17:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        uniq_rules  =  rules . values . uniq 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-05 19:56:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  due_date  &&  start_date  &&  ( start_date_changed?  ||  due_date_changed? )  &&  due_date  <  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-06-05 19:56:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  start_date  &&  start_date_changed?  &&  soonest_start  &&  start_date  <  soonest_start 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-04 17:17:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      errors . add  :start_date ,  :earlier_than_minimum_start_date ,  :date  = >  format_date ( soonest_start ) 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-25 09:35:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      elsif  reopening?  &&  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 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-12 13:40:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  @invalid_parent_issue_id . present? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      errors . add  :parent_issue_id ,  :invalid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elsif  @parent_issue 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-10 17:38:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ! valid_parent_project? ( @parent_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        errors . add  :parent_issue_id ,  :invalid 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-17 15:02:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      elsif  ( @parent_issue  !=  parent )  &&  ( all_dependent_issues . include? ( @parent_issue )  ||  @parent_issue . all_dependent_issues . include? ( self ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        errors . add  :parent_issue_id ,  :invalid 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      elsif  ! new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # moving an existing issue 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-07 20:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  move_possible? ( @parent_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          # move accepted 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-10 17:38:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          errors . add  :parent_issue_id ,  :invalid 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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  } 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-14 18:02:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  v  &&  Array ( v . value ) . detect ( & :present? ) . nil? 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          errors . add  :base ,  v . custom_field . name  +  ' '  +  l ( 'activerecord.errors.messages.blank' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-04 20:49:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  respond_to? ( attribute )  &&  send ( attribute ) . blank?  &&  ! disabled_core_fields . include? ( attribute ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-15 14:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          errors . add  attribute ,  :blank 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-03-01 13:23:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Overrides Redmine::Acts::Customizable::InstanceMethods#validate_custom_field_values 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # so that custom values that are not editable are not validated (eg. a custom field that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # is marked as required should not trigger a validation error if the user is not allowed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # to edit this field). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  validate_custom_field_values 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    user  =  new_record?  ?  author  :  current_journal . try ( :user ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  new_record?  ||  custom_field_values_changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      editable_custom_field_values ( user ) . each ( & :validate_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-22 11:59:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the current journal or nil if it's not initialized 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 15:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 08:03:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the names of attributes that are journalized when updating the issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  journalized_attribute_names 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-14 17:16:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    names  =  Issue . column_names  -  %w( id root_id lft rgt lock_version created_on updated_on closed_on ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      names  -=  tracker . disabled_core_fields 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    names 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 08:03:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-17 09:30:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the initial status of the issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns nil for a new issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  status_was 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-08 11:17:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  status_id_changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  status_id_was . to_i  >  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        @status_was  || =  IssueStatus . find_by_id ( status_id_was ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @status_was  || =  status 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-17 09:30:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-25 17:45:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Return true if the issue is closed, otherwise false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  closed? 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-24 21:40:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    status . present?  &&  status . is_closed? 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-25 17:45:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-25 09:35:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns true if the issue was closed when loaded 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  was_closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    status_was . present?  &&  status_was . is_closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 13:03:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Return true if the issue is being reopened 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-25 09:35:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  reopening? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status_id_changed?  &&  ! closed?  &&  was_closed? 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 13:03:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-25 09:35:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  alias  :reopened?  :reopening? 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-28 09:21:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Return true if the issue is being closed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  closing? 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-25 09:35:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      closed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status_id_changed?  &&  closed?  &&  ! was_closed? 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-28 09:21:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  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? 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-25 09:35:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    due_date . present?  &&  ( due_date  <  Date . today )  &&  ! 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? 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-06 06:27:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    done_date  =  start_date  +  ( ( due_date  -  start_date  +  1 )  *  done_ratio  /  100 ) . floor 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-10 03:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-25 11:14:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    users  =  project . assignable_users . to_a 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-07 17:28:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    versions  =  project . shared_versions . open . to_a 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-27 19:36:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the default status of the issue based on its tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Returns nil if tracker is nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  default_status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tracker . try ( :default_status ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      [ default_status ,  @copied_from . status ] . compact . uniq . sort 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-14 05:45:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      initial_status  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  new_record? 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-26 08:30:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # nop 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 19:45:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      elsif  tracker_id_changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  Tracker . where ( :id  = >  tracker_id_was ,  :default_status_id  = >  status_id_was ) . any? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          initial_status  =  default_status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elsif  tracker . issue_status_ids . include? ( status_id_was ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          initial_status  =  IssueStatus . find_by_id ( status_id_was ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          initial_status  =  default_status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 22:33:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        initial_status  =  status_was 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-14 05:45:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-28 14:58:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      initial_assigned_to_id  =  assigned_to_id_changed?  ?  assigned_to_id_was  :  assigned_to_id 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-08 11:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      assignee_transitions_allowed  =  initial_assigned_to_id . present?  && 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-28 14:58:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ( user . id  ==  initial_assigned_to_id  ||  user . group_ids . include? ( initial_assigned_to_id ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 22:33:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      statuses  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-26 08:30:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      statuses  +=  IssueStatus . new_statuses_allowed ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        initial_status , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        user . admin  ?  Role . all . to_a  :  user . roles_for_project ( project ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tracker , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        author  ==  user , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        assignee_transitions_allowed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-14 05:45:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      statuses  <<  initial_status  unless  statuses . empty? 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-26 08:30:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      statuses  <<  default_status  if  include_default  ||  ( new_record?  &&  statuses . empty? ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-14 05:45:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      statuses  =  statuses . compact . uniq . sort 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-26 22:33:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  blocked? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        statuses . reject! ( & :is_closed? ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      statuses 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-14 05:45:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-06 17:06:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-03-07 08:20:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the previous assignee (user or group) if changed 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-23 17:55:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  assigned_to_was 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-17 20:48:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # assigned_to_id_was is reset before after_save callbacks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    user_id  =  @previous_assigned_to_id  ||  assigned_to_id_was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  user_id  &&  user_id  !=  assigned_to_id 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-07 08:20:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @assigned_to_was  || =  Principal . find_by_id ( user_id ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-23 17:55:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-09-20 11:18:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the original tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  tracker_was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Tracker . find_by_id ( tracker_id_was ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-07-13 09:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  each_notification ( users ,  & block ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  users . any? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  custom_field_values . detect  { | value |  ! value . custom_field . visible? } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        users_by_custom_field_visibility  =  users . group_by  do  | user | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          visible_custom_field_values ( user ) . map ( & :custom_field_id ) . sort 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        users_by_custom_field_visibility . values . each  do  | users | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          yield ( users ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        yield ( users ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-08-14 08:20:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  notify? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @notify  !=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  notify = ( arg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @notify  =  arg 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-04 16:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  total_spent_hours 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:38:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @total_spent_hours  || =  if  leaf? 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 12:09:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      spent_hours 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:38:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self_and_descendants . joins ( :time_entries ) . sum ( " #{ TimeEntry . table_name } .hours " ) . to_f  ||  0 . 0 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 12:09:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-23 12:22:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 11:37:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  total_estimated_hours 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  leaf? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      estimated_hours 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @total_estimated_hours  || =  self_and_descendants . sum ( :estimated_hours ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  relations 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-10 21:59:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @relations  || =  IssueRelation :: Relations . 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? 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-12 19:13:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      relations  =  IssueRelation . where ( " issue_from_id IN (:ids) OR issue_to_id IN (:ids) " ,  :ids  = >  issues . map ( & :id ) ) . all 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-24 15:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:53:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Preloads visible spent time for a collection of issues 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-04 16:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  self . load_visible_spent_hours ( issues ,  user = User . current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  issues . any? 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:53:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      hours_by_issue_id  =  TimeEntry . visible ( user ) . where ( :issue_id  = >  issues . map ( & :id ) ) . group ( :issue_id ) . sum ( :hours ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-04 16:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      issues . each  do  | issue | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . instance_variable_set  " @spent_hours " ,  ( hours_by_issue_id [ issue . id ]  ||  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:38:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:53:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Preloads visible total spent time for a collection of issues 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:38:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  self . load_visible_total_spent_hours ( issues ,  user = User . current ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  issues . any? 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:53:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      hours_by_issue_id  =  TimeEntry . visible ( user ) . joins ( :issue ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        joins ( " JOIN  #{ Issue . table_name }  parent ON parent.root_id =  #{ Issue . table_name } .root_id "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          "  AND parent.lft <=  #{ Issue . table_name } .lft AND parent.rgt >=  #{ Issue . table_name } .rgt " ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        where ( " parent.id IN (?) " ,  issues . map ( & :id ) ) . group ( " parent.id " ) . sum ( :hours ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 12:38:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      issues . each  do  | issue | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        issue . instance_variable_set  " @total_spent_hours " ,  ( hours_by_issue_id [ issue . id ]  ||  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-04 16:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      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 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      relations_from  =  IssueRelation . joins ( :issue_to  = >  :project ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         where ( visible_condition ( user ) ) . where ( :issue_from_id  = >  issue_ids ) . to_a 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-29 12:57:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # Relations with issue_to in given issues and visible issue_from 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      relations_to  =  IssueRelation . joins ( :issue_from  = >  :project ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         where ( visible_condition ( user ) ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         where ( :issue_to_id  = >  issue_ids ) . to_a 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-29 12:57:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      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 } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-10 21:59:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        issue . instance_variable_set  " @relations " ,  IssueRelation :: Relations . new ( issue ,  relations . sort ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-29 12:57:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-04 17:03:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Finds an issue relation given its id. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  find_relation ( relation_id ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-12 19:13:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    IssueRelation . where ( " issue_to_id = ? OR issue_from_id = ? " ,  id ,  id ) . find ( relation_id ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-04 17:03:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-17 15:17:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns all the other issues that depend on the issue 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # The algorithm is a modified breadth first search (bfs) 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-13 13:00:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  all_dependent_issues ( except = [ ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # The found dependencies 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dependencies  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # The visited flag for every node (issue) used by the breadth first search 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eNOT_DISCOVERED          =  0        # The issue is "new" to the algorithm, it has not seen it before. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ePROCESS_ALL             =  1        # The issue is added to the queue. Process both children and relations of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                      # the issue when it is processed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ePROCESS_RELATIONS_ONLY  =  2        # The issue was added to the queue and will be output as dependent issue, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                      # but its children will not be added to the queue when it is processed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eRELATIONS_PROCESSED     =  3        # The related issues, the parent issue and the issue itself have been added to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                      # the queue, but its children have not been added. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ePROCESS_CHILDREN_ONLY   =  4        # The relations and the parent of the issue have been added to the queue, but 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                      # the children still need to be processed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eALL_PROCESSED           =  5        # The issue and all its children, its parent and its related issues have been 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                      # added as dependent issues. It needs no further processing. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    issue_status  =  Hash . new ( eNOT_DISCOVERED ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # The queue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    queue  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Initialize the bfs, add start node (self) to the queue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    queue  <<  self 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    issue_status [ self ]  =  ePROCESS_ALL 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( ! queue . empty? )  do 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      current_issue  =  queue . shift 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_issue_status  =  issue_status [ current_issue ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      dependencies  <<  current_issue 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # Add parent to queue, if not already in it. 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      parent  =  current_issue . parent 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:42:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      parent_status  =  issue_status [ parent ] 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:42:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  parent  &&  ( parent_status  ==  eNOT_DISCOVERED )  &&  ! except . include? ( parent ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        queue  <<  parent 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        issue_status [ parent ]  =  ePROCESS_RELATIONS_ONLY 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # Add children to queue, but only if they are not already in it and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # the children of the current node need to be processed. 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ( current_issue_status  ==  ePROCESS_CHILDREN_ONLY  ||  current_issue_status  ==  ePROCESS_ALL ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        current_issue . children . each  do  | child | 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:45:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          next  if  except . include? ( child ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( issue_status [ child ]  ==  eNOT_DISCOVERED ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            queue  <<  child 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            issue_status [ child ]  =  ePROCESS_ALL 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:45:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          elsif  ( issue_status [ child ]  ==  eRELATIONS_PROCESSED ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            queue  <<  child 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            issue_status [ child ]  =  ePROCESS_CHILDREN_ONLY 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:45:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          elsif  ( issue_status [ child ]  ==  ePROCESS_RELATIONS_ONLY ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            queue  <<  child 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            issue_status [ child ]  =  ePROCESS_ALL 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # Add related issues to the queue, if they are not already in it. 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:42:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      current_issue . relations_from . map ( & :issue_to ) . each  do  | related_issue | 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:45:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        next  if  except . include? ( related_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( issue_status [ related_issue ]  ==  eNOT_DISCOVERED ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:42:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          queue  <<  related_issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          issue_status [ related_issue ]  =  ePROCESS_ALL 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:45:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elsif  ( issue_status [ related_issue ]  ==  eRELATIONS_PROCESSED ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:42:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          queue  <<  related_issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          issue_status [ related_issue ]  =  ePROCESS_CHILDREN_ONLY 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:45:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elsif  ( issue_status [ related_issue ]  ==  ePROCESS_RELATIONS_ONLY ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:42:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          queue  <<  related_issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          issue_status [ related_issue ]  =  ePROCESS_ALL 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # Set new status for current issue 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:39:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ( current_issue_status  ==  ePROCESS_ALL )  ||  ( current_issue_status  ==  ePROCESS_CHILDREN_ONLY ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        issue_status [ current_issue ]  =  eALL_PROCESSED 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:39:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      elsif  ( current_issue_status  ==  ePROCESS_RELATIONS_ONLY ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:37:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        issue_status [ current_issue ]  =  eRELATIONS_PROCESSED 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end  # while 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Remove the issues from the "except" parameter from the result array 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-17 15:17:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dependencies  -=  except 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-12 08:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dependencies . delete ( self ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-26 21:31:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dependencies 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-29 10:06:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns the duration in working days 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  working_duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( start_date  &&  due_date )  ?  working_days ( start_date ,  due_date )  :  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-24 13:43:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  soonest_start ( reload = false ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 09:53:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  @soonest_start . nil?  ||  reload 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      dates  =  relations_to ( reload ) . collect { | relation |  relation . successor_soonest_start } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p  =  @parent_issue  ||  parent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  p  &&  Setting . parent_issue_dates  ==  'derived' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dates  <<  p . soonest_start 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @soonest_start  =  dates . compact . max 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @soonest_start 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 15:29:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-29 10:06:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Sets start_date on the given date or the next working day 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # and changes due_date to keep the same working duration. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  reschedule_on ( date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    wd  =  working_duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    date  =  next_working_date ( date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . start_date  =  date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . due_date  =  add_working_days ( date ,  wd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Reschedules the issue on the given date or the next working day and saves the record. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # If the issue is a parent task, this is done by rescheduling its subtasks. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  reschedule_on! ( date ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 15:29:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  if  date . nil? 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 09:53:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  leaf?  ||  ! dates_derived? 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-24 13:43:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  start_date . nil?  ||  start_date  !=  date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  start_date  &&  start_date  >  date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          # Issue can not be moved earlier than its soonest start date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          date  =  [ soonest_start ( true ) ,  date ] . compact . max 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-29 10:06:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        reschedule_on ( date ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-12 19:41:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        begin 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        rescue  ActiveRecord :: StaleObjectError 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          reload 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-29 10:06:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          reschedule_on ( date ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-12 19:41:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 15:29:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      leaves . each  do  | leaf | 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-24 15:09:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  leaf . start_date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          # Only move subtask if it starts at the same date as the parent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          # or if it starts before the given date 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-08 11:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          if  start_date  ==  leaf . start_date  ||  date  >  leaf . start_date 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-24 15:09:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            leaf . reschedule_on! ( date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          leaf . reschedule_on! ( date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 15:29:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-05 13:22:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 09:53:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  dates_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ! leaf?  &&  Setting . parent_issue_dates  ==  'derived' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  priority_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ! leaf?  &&  Setting . parent_issue_priority  ==  'derived' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 10:03:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  done_ratio_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ! leaf?  &&  Setting . parent_issue_done_ratio  ==  'derived' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-11 19:35:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  css_classes ( user = User . current ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-01 10:42:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    s  =  " issue tracker- #{ tracker_id }  status- #{ status_id }   #{ priority . try ( :css_classes ) } " 
							 
						 
					
						
							
								
									
										
										
										
											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? 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-11 19:35:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  user . logged? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      s  <<  ' created-by-me'  if  author_id  ==  user . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      s  <<  ' assigned-to-me'  if  assigned_to_id  ==  user . id 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-06 12:16:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      s  <<  ' assigned-to-my-group'  if  user . groups . any?  { | g |  g . id  ==  assigned_to_id } 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-11 19:35:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-25 11:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-06 10:28:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-08 11:22:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Issue . update_versions ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ " #{ Version . table_name } .project_id IN (?) OR  #{ Issue . table_name } .project_id IN (?) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             moved_project_ids ,  moved_project_ids ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-08 20:47:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  parent_issue_id = ( arg ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-12 13:40:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    s  =  arg . to_s . strip . presence 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  s  &&  ( m  =  s . match ( %r{ \ A # ?( \ d+) \ z } ) )  &&  ( @parent_issue  =  Issue . find_by_id ( m [ 1 ] ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-20 09:25:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @invalid_parent_issue_id  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elsif  s . blank? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @parent_issue  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @invalid_parent_issue_id  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @parent_issue  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-12 13:40:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @invalid_parent_issue_id  =  arg 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  parent_issue_id 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-12 13:40:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  @invalid_parent_issue_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @invalid_parent_issue_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elsif  instance_variable_defined?  :@parent_issue 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      @parent_issue . nil?  ?  nil  :  @parent_issue . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      parent_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-01-07 20:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  set_parent_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . parent_id  =  parent_issue_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-17 10:17:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns true if issue's project is a valid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # parent issue project 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-10 17:38:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  valid_parent_project? ( issue = parent ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true  if  issue . nil?  ||  issue . project_id  ==  project_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Setting . cross_project_subtasks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    when  'system' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    when  'tree' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issue . project . root  ==  project . root 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    when  'hierarchy' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issue . project . is_or_is_ancestor_of? ( project )  ||  issue . project . is_descendant_of? ( project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    when  'descendants' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issue . project . is_or_is_ancestor_of? ( project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-09-14 10:42:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns an issue scope based on project and scope 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . cross_project_scope ( project ,  scope = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  project . nil? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  Issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  scope 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    when  'all' ,  'system' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    when  'tree' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Issue . joins ( :project ) . where ( " ( #{ Project . table_name } .lft >= :lft AND  #{ Project . table_name } .rgt <= :rgt) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                  :lft  = >  project . root . lft ,  :rgt  = >  project . root . rgt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    when  'hierarchy' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Issue . joins ( :project ) . where ( " ( #{ Project . table_name } .lft >= :lft AND  #{ Project . table_name } .rgt <= :rgt) OR ( #{ Project . table_name } .lft < :lft AND  #{ Project . table_name } .rgt > :rgt) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                  :lft  = >  project . lft ,  :rgt  = >  project . rgt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    when  'descendants' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Issue . joins ( :project ) . where ( " ( #{ Project . table_name } .lft >= :lft AND  #{ Project . table_name } .rgt <= :rgt) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                  :lft  = >  project . lft ,  :rgt  = >  project . rgt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Issue . where ( :project_id  = >  project . id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  self . by_tracker ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project ,  :association  = >  :tracker ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_version ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project ,  :association  = >  :fixed_version ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_priority ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project ,  :association  = >  :priority ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_category ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project ,  :association  = >  :category ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_assigned_to ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project ,  :association  = >  :assigned_to ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_author ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count_and_group_by ( :project  = >  project ,  :association  = >  :author ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-03 16:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . by_subproject ( project ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    r  =  count_and_group_by ( :project  = >  project ,  :with_subprojects  = >  true ,  :association  = >  :project ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    r . reject  { | r |  r [ " project_id " ]  ==  project . id . to_s } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Query generator for selecting groups of issue counts for a project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # based on specific criteria 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * project - Project to search in. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * with_subprojects - Includes subprojects issues if set to true. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # * association - Symbol. Association for grouping. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . count_and_group_by ( options ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assoc  =  reflect_on_association ( options [ :association ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    select_field  =  assoc . foreign_key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Issue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      visible ( User . current ,  :project  = >  options [ :project ] ,  :with_subprojects  = >  options [ :with_subprojects ] ) . 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 21:47:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      joins ( :status ,  assoc . name ) . 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      group ( :status_id ,  :is_closed ,  select_field ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      count . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      map  do  | columns ,  total | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        status_id ,  is_closed ,  field_value  =  columns 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-21 18:44:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        is_closed  =  [ 't' ,  'true' ,  '1' ] . include? ( is_closed . to_s ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " status_id "  = >  status_id . to_s , 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-21 17:47:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          " closed "  = >  is_closed , 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-20 19:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          select_field  = >  field_value . to_s , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " total "  = >  total . to_s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-06-11 16:54:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns a scope of projects that user can assign the issue to 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  allowed_target_projects ( user = User . current ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-08 10:20:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    current_project  =  new_record?  ?  nil  :  project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . class . allowed_target_projects ( user ,  current_project ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-08 11:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-02-08 10:20:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Returns a scope of projects that user can assign issues to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # If current_project is given, it will be included in the scope 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  self . allowed_target_projects ( user = User . current ,  current_project = nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    condition  =  Project . allowed_to_condition ( user ,  :add_issues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  current_project 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      condition  =  [ " ( #{ condition } ) OR  #{ Project . table_name } .id = ? " ,  current_project . id ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-20 11:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Project . where ( condition ) . having_trackers 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-08 12:20:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TimeEntry . where ( { :issue_id  = >  id } ) . update_all ( [ " project_id = ? " ,  project_id ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Delete issue relations 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    unless  Setting . cross_project_issue_relations? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      relations_from . clear 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      relations_to . clear 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-10 17:38:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # Move subtasks that were in the same project 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-06 19:50:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    children . each  do  | child | 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-10 17:38:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      next  unless  child . project_id  ==  project_id_was 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 15:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  @current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        @copied_from . init_journal ( @current_journal . user ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-01 12:26:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      copy_options  =  ( @copy_options  ||  { } ) . merge ( :subtasks  = >  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      copied_issue_ids  =  { @copied_from . id  = >  self . id } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      @copied_from . reload . descendants . reorder ( " #{ Issue . table_name } .lft " ) . each  do  | child | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Do not copy self when copying an issue as a descendant of the copied issue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        next  if  child  ==  self 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Do not copy subtasks of issues that were not copied 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        next  unless  copied_issue_ids [ child . parent_id ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Do not copy subtasks that are not visible to avoid potential disclosure of private data 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        unless  child . visible? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          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 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-01 12:26:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        copy  =  Issue . new . copy_from ( child ,  copy_options ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 15:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  @current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          copy . init_journal ( @current_journal . user ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        copy . author  =  author 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        copy . project  =  project 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-01 12:26:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        copy . parent_issue_id  =  copied_issue_ids [ child . parent_id ] 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-01 12:26:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          next 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-01 12:26:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        copied_issue_ids [ child . id ]  =  copy . id 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 05:34:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      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 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-07 20:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  parent_id_changed? 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-20 09:25:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      update_nested_set_attributes_on_parent_change 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    remove_instance_variable ( :@parent_issue )  if  instance_variable_defined? ( :@parent_issue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Updates the nested set for when an existing issue is moved 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  update_nested_set_attributes_on_parent_change 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-07 20:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    former_parent_id  =  parent_id_was 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-20 09:25:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # delete invalid relations of all descendants 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self_and_descendants . each  do  | issue | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      issue . relations . each  do  | relation | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        relation . destroy  unless  relation . valid? 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-20 09:25:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # update former parent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    recalculate_attributes_for ( former_parent_id )  if  former_parent_id 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  update_parent_attributes 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-07 20:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  parent_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      recalculate_attributes_for ( parent_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      association ( :parent ) . reset 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-30 02:45:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  recalculate_attributes_for ( issue_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  issue_id  &&  p  =  Issue . find_by_id ( issue_id ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 09:53:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  p . priority_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # priority = highest priority of children 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  priority_position  =  p . children . joins ( :priority ) . maximum ( " #{ IssuePriority . table_name } .position " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          p . priority  =  IssuePriority . find_by_position ( priority_position ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 09:53:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  p . dates_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 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 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-05-25 10:03:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  p . done_ratio_derived? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # done ratio = weighted average ratio of leaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        unless  Issue . use_status_for_done_ratio?  &&  p . status  &&  p . status . default_done_ratio 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          leaves_count  =  p . leaves . count 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  leaves_count  >  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            average  =  p . leaves . where ( " estimated_hours > 0 " ) . average ( :estimated_hours ) . to_f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  average  ==  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              average  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            done  =  p . leaves . joins ( :status ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              sum ( " COALESCE(CASE WHEN estimated_hours > 0 THEN estimated_hours ELSE NULL END,  #{ average } )  "  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  " * (CASE WHEN is_closed =  #{ self . class . connection . quoted_true }  THEN 100 ELSE COALESCE(done_ratio, 0) END) " ) . to_f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            progress  =  done  /  ( average  *  leaves_count ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p . done_ratio  =  progress . round 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-13 14:56:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-22 17:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Issue . joins ( :project ,  :fixed_version ) . 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-12 19:13:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      where ( " #{ Issue . table_name } .fixed_version_id IS NOT NULL "  + 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-18 15:02:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        "  AND  #{ Issue . table_name } .project_id <>  #{ Version . table_name } .project_id "  + 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-12 19:13:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        "  AND  #{ Version . table_name } .sharing <> 'system' " ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      where ( conditions ) . 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 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 08:03:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  attachment_added ( attachment ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  current_journal  &&  ! attachment . new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_journal . journalize_attachment ( attachment ,  :added ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-24 09:34:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 16:54:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Callback on attachment deletion 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 08:03:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  attachment_removed ( attachment ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  current_journal  &&  ! attachment . new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_journal . journalize_attachment ( attachment ,  :removed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_journal . save 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-04 11:41:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 16:54:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 02:14:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 15:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Called after a relation is added 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  relation_added ( relation ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 08:03:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_journal . journalize_relation ( relation ,  :added ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_journal . save 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 15:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Called after a relation is removed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  relation_removed ( relation ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 08:03:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_journal . journalize_relation ( relation ,  :removed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_journal . save 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-02 15:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 | 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-07 08:07:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # Reload is needed in case the duplicate was updated by a previous duplicate 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-28 09:21:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-16 09:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Make sure updated_on is updated when adding a note and set updated_on now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # so we can set closed_on with the same value on closing 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-21 18:23:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  force_updated_on_change 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-16 09:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  @current_journal  ||  changed? 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-21 18:23:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . updated_on  =  current_time_from_proper_timezone 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-16 09:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  new_record? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . created_on  =  updated_on 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Callback for setting closed_on when the issue is closed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # The closed_on attribute stores the time of the last closing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # and is preserved when the issue is reopened. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  update_closed_on 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-25 09:35:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  closing? 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-16 09:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . closed_on  =  updated_on 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-21 18:23:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 19:11:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Saves the changes in a Journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Called after_save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  create_journal 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-05 08:03:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  current_journal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      current_journal . save 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 19:11:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-04 17:24:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-07-14 14:26:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  send_notification 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-14 08:20:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  notify?  &&  Setting . notified_events . include? ( 'issue_added' ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-14 14:26:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      Mailer . deliver_issue_add ( self ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-12-17 20:48:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Stores the previous assignee so we can still have access 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # to it during after_save callbacks (assigned_to_id_was is reset) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  set_assigned_to_was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @previous_assigned_to_id  =  assigned_to_id_was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Clears the previous assignee at the end of after_save callbacks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  clear_assigned_to_was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @assigned_to_was  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @previous_assigned_to_id  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-14 17:16:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  clear_disabled_fields 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  tracker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      tracker . disabled_core_fields . each  do  | attribute | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        send  " #{ attribute } = " ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      end 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-09 09:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . done_ratio  || =  0 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-14 17:16:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  end 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-28 18:11:03 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								end