@ -1,22 +1,22 @@
require 'date'
class Sprint < Version
unloadable
unloadable
validate :start_and_end_dates
validate :start_and_end_dates
named_scope :open_sprints , lambda { | project |
{
:order = > 'start_date ASC, effective_date ASC' ,
:conditions = > [ " versions.status = 'open' and versions.project_id = ? " , project . id ]
}
named_scope :open_sprints , lambda { | project |
{
:order = > 'start_date ASC, effective_date ASC' ,
:conditions = > [ " versions.status = 'open' and versions.project_id = ? " , project . id ]
}
}
named_scope :order_by_date , :order = > 'start_date ASC, effective_date ASC'
named_scope :order_by_name , :order = > " #{ Version . table_name } .name ASC "
named_scope :order_by_date , :order = > 'start_date ASC, effective_date ASC'
named_scope :order_by_name , :order = > " #{ Version . table_name } .name ASC "
named_scope :apply_to , lambda { | project | { :include = > :project ,
:conditions = > [ " #{ Version . table_name } .project_id = #{ project . id } " +
named_scope :apply_to , lambda { | project | { :include = > :project ,
:conditions = > [ " #{ Version . table_name } .project_id = #{ project . id } " +
" OR ( #{ Project . table_name } .status = #{ Project :: STATUS_ACTIVE } AND ( " +
" #{ Version . table_name } .sharing = 'system' " +
" OR ( #{ Project . table_name } .lft >= #{ project . root . lft } AND #{ Project . table_name } .rgt <= #{ project . root . rgt } AND #{ Version . table_name } .sharing = 'tree') " +
@ -24,116 +24,114 @@ class Sprint < Version
" OR ( #{ Project . table_name } .lft > #{ project . lft } AND #{ Project . table_name } .rgt < #{ project . rgt } AND #{ Version . table_name } .sharing = 'hierarchy') " +
" )) " ] } }
named_scope :displayed_left , lambda { | project | { :joins = > sanitize_sql_array ( [ " LEFT OUTER JOIN (SELECT * from #{ VersionSetting . table_name } " +
" WHERE project_id = ? ) version_settings " +
" ON version_settings.version_id = versions.id " ,
project . id ] ) ,
:conditions = > [ " (version_settings.project_id = ? AND version_settings.display = ?) " +
" OR (version_settings.project_id is NULL) " ,
project . id , VersionSetting :: DISPLAY_LEFT ] } }
named_scope :displayed_left , lambda { | project | { :joins = > sanitize_sql_array ( [ " LEFT OUTER JOIN (SELECT * from #{ VersionSetting . table_name } " +
" WHERE project_id = ? ) version_settings " +
" ON version_settings.version_id = versions.id " ,
project . id ] ) ,
:conditions = > [ " (version_settings.project_id = ? AND version_settings.display = ?) " +
" OR (version_settings.project_id is NULL) " ,
project . id , VersionSetting :: DISPLAY_LEFT ] } }
named_scope :displayed_right , lambda { | project | { :include = > :version_settings ,
:conditions = > [ " version_settings.project_id = ? AND version_settings.display = ? " ,
project . id , VersionSetting :: DISPLAY_RIGHT ] } }
named_scope :displayed_right , lambda { | project | { :include = > :version_settings ,
:conditions = > [ " version_settings.project_id = ? AND version_settings.display = ? " ,
project . id , VersionSetting :: DISPLAY_RIGHT ] } }
def stories ( project , options = { } )
Story . sprint_backlog ( project , self , options )
end
def points
stories . inject ( 0 ) { | sum , story | sum + story . story_points . to_i }
end
def stories ( project , options = { } )
Story . sprint_backlog ( project , self , options )
end
def has_wiki_page
return false if wiki_page_title . blank?
def points
return stories . inject ( 0 ) { | sum , story | sum + story . story_points . to_i }
end
page = project . wiki . find_page ( self . wiki_page_title )
return false if ! page
def has_wiki_page
return false if wiki_page_title . blank?
template = project . wiki . find_page ( Setting . plugin_redmine_backlogs [ :wiki_template ] )
return false if template && page . text == template . text
page = project . wiki . find_page ( self . wiki_page_title )
return false if ! page
true
end
template = project . wiki . find_page ( Setting . plugin_redmine_backlogs [ :wiki_template ] )
return false if template && page . text == template . text
def wiki_page
return '' unless project . wiki
return true
end
self . update_attribute ( :wiki_page_title , Wiki . titleize ( self . name ) ) if wiki_page_title . blank?
def wiki_page
if ! project . wiki
return ''
end
page = project . wiki . find_page ( self . wiki_page_title )
template = project . wiki . find_page ( Setting . plugin_redmine_backlogs [ :wiki_template ] )
self . update_attribute ( :wiki_page_title , Wiki . titleize ( self . name ) ) if wiki_page_title . blank?
if template and not page
page = project . wiki . pages . build ( :title = > self . wiki_page_title )
page . build_content ( :text = > " h1. #{ self . name } \n \n #{ template . text } " )
page . save!
end
page = project . wiki . find_page ( self . wiki_page_title )
template = project . wiki . find_page ( Setting . plugin_redmine_backlogs [ :wiki_template ] )
wiki_page_title
en d
if template and not page
page = WikiPage . new ( :wiki = > project . wiki , :title = > self . wiki_page_title )
page . content = WikiContent . new
page . content . text = " h1. #{ self . name } \n \n #{ template . text } "
page . save!
end
def days ( cutoff = nil , alldays = false )
# assumes mon-fri are working days, sat-sun are not. this
# assumption is not globally right, we need to make this configurable.
cutoff = self . effective_date if cutoff . nil?
return wiki_page_title
end
( self . start_date .. cutoff ) . select { | d | alldays || ( d . wday > 0 and d . wday < 6 ) }
end
def days ( cutoff = nil , alldays = false )
# assumes mon-fri are working days, sat-sun are not. this
# assumption is not globally right, we need to make this configurable.
cutoff = self . effective_date if cutoff . nil?
return ( self . start_date .. cutoff ) . select { | d | alldays || ( d . wday > 0 and d . wday < 6 ) }
end
def eta
return nil unless self . start_date
def eta
return nil if ! self . start_date
dpp = self . project . scrum_statistics . info [ :average_days_per_point ]
return nil unless dpp
dpp = self . project . scrum_statistics . info [ :average_days_per_point ]
return nil if ! dpp
# assume 5 out of 7 are working days
self . start_date + Integer ( self . points * dpp * 7 . 0 / 5 )
end
# assume 5 out of 7 are working days
return self . start_date + Integer ( self . points * dpp * 7 . 0 / 5 )
end
def has_burndown?
! ! ( self . effective_date and self . start_date )
end
def has_burndown?
! ! ( self . effective_date and self . start_date )
end
def activity
bd = self . burndown ( 'up' )
r etur n false if b d . blank?
def activity
bd = self . burndown ( 'up' )
return false if ! bd
# assume a sprint is active if it's only 2 days old
return true if bd . remaining_hours . size < = 2
# assume a sprint is active if it's only 2 days old
return true if bd . remaining_hours . size < = 2
Issue . exists? ( [ 'fixed_version_id = ? and ((updated_on between ? and ?) or (created_on between ? and ?))' ,
self . id , - 2 . days . from_now , Time . now , - 2 . days . from_now , Time . now ] )
end
return Issue . exists? ( [ 'fixed_version_id = ? and ((updated_on between ? and ?) or (created_on between ? and ?))' , self . id , - 2 . days . from_now , Time . now , - 2 . days . from_now , Time . now ] )
end
def burndown ( project , burn_direction = nil )
return nil if not self . has_burndown?
@cached_burndown || = Burndown . new ( self , project , burn_direction )
return @cached_burndown
end
def burndown ( project , burn_direction = nil )
return nil unless self . has_burndown?
def self . generate_burndown ( only_current = true )
if only_current
conditions = [ " ? between start_date and effective_date " , Date . today ]
else
conditions = " 1 = 1 "
end
@cached_burndown || = Burndown . new ( self , project , burn_direction )
end
Version . find ( :all , :conditions = > conditions ) . each { | sprint |
sprint . burndown
}
def self . generate_burndown ( only_current = true )
if only_current
conditions = [ " ? BETWEEN start_date AND effective_date " , Date . today ]
else
conditions = " 1 = 1 "
end
def impediments ( project )
Impediment . find ( :all , :conditions = > { :fixed_version_id = > self , :project_id = > project } )
end
Version . find ( :all , :conditions = > conditions ) . each { | sprint |
sprint . burndown
}
end
private
def start_and_end_dates
errors . add_to_base ( :cannot_end_before_it_starts ) if self . effective_date && self . start_date && self . start_date > = self . effective_date
end
def impediments ( project )
Impediment . find ( :all , :conditions = > { :fixed_version_id = > self , :project_id = > project } )
end
private
def start_and_end_dates
if self . effective_date && self . start_date && self . start_date > = self . effective_date
errors . add_to_base ( :cannot_end_before_it_starts )
end
end
end