end
def soonest_start
- @soonest_start ||= relations_to.collect{|relation| relation.successor_soonest_start}.compact.min
+ @soonest_start ||= (
+ relations_to.collect{|relation| relation.successor_soonest_start} +
+ ancestors.collect(&:soonest_start)
+ ).compact.max
+ end
+
+ def reschedule_after(date)
+ return if date.nil?
+ if leaf?
+ if start_date.nil? || start_date < date
+ self.start_date, self.due_date = date, date + duration
+ save
+ end
+ else
+ leaves.each do |leaf|
+ leaf.reschedule_after(date)
+ end
+ end
end
def <=>(issue)
def set_issue_to_dates
soonest_start = self.successor_soonest_start
- if soonest_start && (!issue_to.start_date || issue_to.start_date < soonest_start)
- issue_to.start_date, issue_to.due_date = successor_soonest_start, successor_soonest_start + issue_to.duration
- issue_to.save
+ if soonest_start
+ issue_to.reschedule_after(soonest_start)
end
end
create_issue!(:estimated_hours => 7, :parent_issue_id => parent.id)
assert_equal 12, parent.reload.estimated_hours
end
+
+
+ def test_reschuling_a_parent_should_reschedule_subtasks
+ parent = create_issue!
+ c1 = create_issue!(:start_date => '2010-05-12', :due_date => '2010-05-18', :parent_issue_id => parent.id)
+ c2 = create_issue!(:start_date => '2010-06-03', :due_date => '2010-06-10', :parent_issue_id => parent.id)
+ parent.reload
+ parent.reschedule_after(Date.parse('2010-06-02'))
+ c1.reload
+ assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-08')], [c1.start_date, c1.due_date]
+ c2.reload
+ assert_equal [Date.parse('2010-06-03'), Date.parse('2010-06-10')], [c2.start_date, c2.due_date] # no change
+ parent.reload
+ assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-10')], [parent.start_date, parent.due_date]
+ end
def test_project_copy_should_copy_issue_tree
p = Project.create!(:name => 'Tree copy', :identifier => 'tree-copy', :tracker_ids => [1, 2])