@@ -0,0 +1,15 | |||||
|
1 | class ClearEstimatedHoursOnParentIssues < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | # Clears estimated hours on parent issues | |||
|
4 | Issue.where("rgt > lft + 1 AND estimated_hours > 0").update_all :estimated_hours => nil | |||
|
5 | end | |||
|
6 | ||||
|
7 | def self.down | |||
|
8 | table_name = Issue.table_name | |||
|
9 | leaves_sum_select = "SELECT SUM(leaves.estimated_hours) FROM #{table_name} leaves" + | |||
|
10 | " WHERE leaves.root_id = #{table_name}.root_id AND leaves.lft > #{table_name}.lft AND leaves.rgt < #{table_name}.rgt" + | |||
|
11 | " AND leaves.rgt = leaves.lft + 1" | |||
|
12 | ||||
|
13 | Issue.where("rgt > lft + 1").update_all "estimated_hours = (#{leaves_sum_select})" | |||
|
14 | end | |||
|
15 | end |
@@ -113,6 +113,14 module IssuesHelper | |||||
113 | s.html_safe |
|
113 | s.html_safe | |
114 | end |
|
114 | end | |
115 |
|
115 | |||
|
116 | def issue_estimated_hours_details(issue) | |||
|
117 | s = issue.estimated_hours.present? ? l_hours(issue.estimated_hours) : "" | |||
|
118 | unless issue.leaf? || issue.total_estimated_hours.nil? | |||
|
119 | s << " (#{l(:label_total)}: #{l_hours(issue.total_estimated_hours)})" | |||
|
120 | end | |||
|
121 | s.html_safe | |||
|
122 | end | |||
|
123 | ||||
116 | # Returns an array of error messages for bulk edited issues |
|
124 | # Returns an array of error messages for bulk edited issues | |
117 | def bulk_edit_error_messages(issues) |
|
125 | def bulk_edit_error_messages(issues) | |
118 | messages = {} |
|
126 | messages = {} |
@@ -206,6 +206,7 class Issue < ActiveRecord::Base | |||||
206 | @assignable_versions = nil |
|
206 | @assignable_versions = nil | |
207 | @relations = nil |
|
207 | @relations = nil | |
208 | @spent_hours = nil |
|
208 | @spent_hours = nil | |
|
209 | @total_estimated_hours = nil | |||
209 | base_reload(*args) |
|
210 | base_reload(*args) | |
210 | end |
|
211 | end | |
211 |
|
212 | |||
@@ -435,9 +436,6 class Issue < ActiveRecord::Base | |||||
435 | if done_ratio_derived? |
|
436 | if done_ratio_derived? | |
436 | names -= %w(done_ratio) |
|
437 | names -= %w(done_ratio) | |
437 | end |
|
438 | end | |
438 | unless leaf? |
|
|||
439 | names -= %w(estimated_hours) |
|
|||
440 | end |
|
|||
441 | names |
|
439 | names | |
442 | end |
|
440 | end | |
443 |
|
441 | |||
@@ -929,6 +927,14 class Issue < ActiveRecord::Base | |||||
929 | sum("#{TimeEntry.table_name}.hours").to_f || 0.0 |
|
927 | sum("#{TimeEntry.table_name}.hours").to_f || 0.0 | |
930 | end |
|
928 | end | |
931 |
|
929 | |||
|
930 | def total_estimated_hours | |||
|
931 | if leaf? | |||
|
932 | estimated_hours | |||
|
933 | else | |||
|
934 | @total_estimated_hours ||= self_and_descendants.sum(:estimated_hours) | |||
|
935 | end | |||
|
936 | end | |||
|
937 | ||||
932 | def relations |
|
938 | def relations | |
933 | @relations ||= IssueRelation::Relations.new(self, (relations_from + relations_to).sort) |
|
939 | @relations ||= IssueRelation::Relations.new(self, (relations_from + relations_to).sort) | |
934 | end |
|
940 | end | |
@@ -1488,10 +1494,6 class Issue < ActiveRecord::Base | |||||
1488 | end |
|
1494 | end | |
1489 | end |
|
1495 | end | |
1490 |
|
1496 | |||
1491 | # estimate = sum of leaves estimates |
|
|||
1492 | p.estimated_hours = p.leaves.sum(:estimated_hours).to_f |
|
|||
1493 | p.estimated_hours = nil if p.estimated_hours == 0.0 |
|
|||
1494 |
|
||||
1495 | # ancestors will be recursively updated |
|
1497 | # ancestors will be recursively updated | |
1496 | p.save(:validate => false) |
|
1498 | p.save(:validate => false) | |
1497 | end |
|
1499 | end |
@@ -83,7 +83,7 class Version < ActiveRecord::Base | |||||
83 | # Returns the total estimated time for this version |
|
83 | # Returns the total estimated time for this version | |
84 | # (sum of leaves estimated_hours) |
|
84 | # (sum of leaves estimated_hours) | |
85 | def estimated_hours |
|
85 | def estimated_hours | |
86 |
@estimated_hours ||= fixed_issues. |
|
86 | @estimated_hours ||= fixed_issues.sum(:estimated_hours).to_f | |
87 | end |
|
87 | end | |
88 |
|
88 | |||
89 | # Returns the total reported time for this version |
|
89 | # Returns the total reported time for this version |
@@ -58,8 +58,8 | |||||
58 | rows.right l(:field_done_ratio), progress_bar(@issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%"), :class => 'progress' |
|
58 | rows.right l(:field_done_ratio), progress_bar(@issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%"), :class => 'progress' | |
59 | end |
|
59 | end | |
60 | unless @issue.disabled_core_fields.include?('estimated_hours') |
|
60 | unless @issue.disabled_core_fields.include?('estimated_hours') | |
61 | unless @issue.estimated_hours.nil? |
|
61 | unless @issue.total_estimated_hours.nil? | |
62 |
rows.right l(:field_estimated_hours), |
|
62 | rows.right l(:field_estimated_hours), issue_estimated_hours_details(@issue), :class => 'estimated-hours' | |
63 | end |
|
63 | end | |
64 | end |
|
64 | end | |
65 | if User.current.allowed_to?(:view_time_entries, @project) |
|
65 | if User.current.allowed_to?(:view_time_entries, @project) |
@@ -287,26 +287,6 class IssueNestedSetTest < ActiveSupport::TestCase | |||||
287 | end |
|
287 | end | |
288 | end |
|
288 | end | |
289 |
|
289 | |||
290 | def test_parent_estimate_should_be_sum_of_leaves |
|
|||
291 | parent = Issue.generate! |
|
|||
292 | parent.generate_child!(:estimated_hours => nil) |
|
|||
293 | assert_equal nil, parent.reload.estimated_hours |
|
|||
294 | parent.generate_child!(:estimated_hours => 5) |
|
|||
295 | assert_equal 5, parent.reload.estimated_hours |
|
|||
296 | parent.generate_child!(:estimated_hours => 7) |
|
|||
297 | assert_equal 12, parent.reload.estimated_hours |
|
|||
298 | end |
|
|||
299 |
|
||||
300 | def test_move_parent_updates_old_parent_attributes |
|
|||
301 | first_parent = Issue.generate! |
|
|||
302 | second_parent = Issue.generate! |
|
|||
303 | child = first_parent.generate_child!(:estimated_hours => 5) |
|
|||
304 | assert_equal 5, first_parent.reload.estimated_hours |
|
|||
305 | child.update_attributes(:estimated_hours => 7, :parent_issue_id => second_parent.id) |
|
|||
306 | assert_equal 7, second_parent.reload.estimated_hours |
|
|||
307 | assert_nil first_parent.reload.estimated_hours |
|
|||
308 | end |
|
|||
309 |
|
||||
310 | def test_project_copy_should_copy_issue_tree |
|
290 | def test_project_copy_should_copy_issue_tree | |
311 | p = Project.create!(:name => 'Tree copy', :identifier => 'tree-copy', :tracker_ids => [1, 2]) |
|
291 | p = Project.create!(:name => 'Tree copy', :identifier => 'tree-copy', :tracker_ids => [1, 2]) | |
312 | i1 = Issue.generate!(:project => p, :subject => 'i1') |
|
292 | i1 = Issue.generate!(:project => p, :subject => 'i1') |
@@ -146,23 +146,41 class IssueSubtaskingTest < ActiveSupport::TestCase | |||||
146 | end |
|
146 | end | |
147 |
|
147 | |||
148 | def test_done_ratio_of_parent_with_a_child_without_estimated_time_should_not_exceed_100 |
|
148 | def test_done_ratio_of_parent_with_a_child_without_estimated_time_should_not_exceed_100 | |
149 | parent = Issue.generate! |
|
149 | with_settings :parent_issue_done_ratio => 'derived' do | |
150 | parent.generate_child!(:estimated_hours => 40) |
|
150 | parent = Issue.generate! | |
151 | parent.generate_child!(:estimated_hours => 40) |
|
151 | parent.generate_child!(:estimated_hours => 40) | |
152 |
parent.generate_child!(:estimated_hours => |
|
152 | parent.generate_child!(:estimated_hours => 40) | |
153 | parent.generate_child! |
|
153 | parent.generate_child!(:estimated_hours => 20) | |
154 | parent.reload.children.each(&:close!) |
|
154 | parent.generate_child! | |
155 | assert_equal 100, parent.reload.done_ratio |
|
155 | parent.reload.children.each(&:close!) | |
|
156 | assert_equal 100, parent.reload.done_ratio | |||
|
157 | end | |||
156 | end |
|
158 | end | |
157 |
|
159 | |||
158 | def test_done_ratio_of_parent_with_a_child_with_estimated_time_at_0_should_not_exceed_100 |
|
160 | def test_done_ratio_of_parent_with_a_child_with_estimated_time_at_0_should_not_exceed_100 | |
159 | parent = Issue.generate! |
|
161 | with_settings :parent_issue_done_ratio => 'derived' do | |
160 | parent.generate_child!(:estimated_hours => 40) |
|
162 | parent = Issue.generate! | |
161 | parent.generate_child!(:estimated_hours => 40) |
|
163 | parent.generate_child!(:estimated_hours => 40) | |
162 |
parent.generate_child!(:estimated_hours => |
|
164 | parent.generate_child!(:estimated_hours => 40) | |
163 | parent.generate_child!(:estimated_hours => 0) |
|
165 | parent.generate_child!(:estimated_hours => 20) | |
164 | parent.reload.children.each(&:close!) |
|
166 | parent.generate_child!(:estimated_hours => 0) | |
165 | assert_equal 100, parent.reload.done_ratio |
|
167 | parent.reload.children.each(&:close!) | |
|
168 | assert_equal 100, parent.reload.done_ratio | |||
|
169 | end | |||
|
170 | end | |||
|
171 | ||||
|
172 | def test_changing_parent_should_update_previous_parent_done_ratio | |||
|
173 | with_settings :parent_issue_done_ratio => 'derived' do | |||
|
174 | first_parent = Issue.generate! | |||
|
175 | second_parent = Issue.generate! | |||
|
176 | first_parent.generate_child!(:done_ratio => 40) | |||
|
177 | child = first_parent.generate_child!(:done_ratio => 20) | |||
|
178 | assert_equal 30, first_parent.reload.done_ratio | |||
|
179 | assert_equal 0, second_parent.reload.done_ratio | |||
|
180 | child.update_attributes(:parent_issue_id => second_parent.id) | |||
|
181 | assert_equal 40, first_parent.reload.done_ratio | |||
|
182 | assert_equal 20, second_parent.reload.done_ratio | |||
|
183 | end | |||
166 | end |
|
184 | end | |
167 |
|
185 | |||
168 | def test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_independent |
|
186 | def test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_independent | |
@@ -227,4 +245,14 class IssueSubtaskingTest < ActiveSupport::TestCase | |||||
227 | assert_equal 0, parent.reload.done_ratio |
|
245 | assert_equal 0, parent.reload.done_ratio | |
228 | end |
|
246 | end | |
229 | end |
|
247 | end | |
|
248 | ||||
|
249 | def test_parent_total_estimated_hours_should_be_sum_of_descendants | |||
|
250 | parent = Issue.generate! | |||
|
251 | parent.generate_child!(:estimated_hours => nil) | |||
|
252 | assert_equal 0, parent.reload.total_estimated_hours | |||
|
253 | parent.generate_child!(:estimated_hours => 5) | |||
|
254 | assert_equal 5, parent.reload.total_estimated_hours | |||
|
255 | parent.generate_child!(:estimated_hours => 7) | |||
|
256 | assert_equal 12, parent.reload.total_estimated_hours | |||
|
257 | end | |||
230 | end |
|
258 | end |
General Comments 0
You need to be logged in to leave comments.
Login now