From f37306aace92f684806cc95dcced0ac5fd7c9b94 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Wed, 29 Sep 2010 10:54:33 -0700 Subject: [PATCH] [#4552] Add the Overhead hours spent to the Deliverable details --- app/models/deliverable.rb | 11 +++- app/models/hourly_deliverable.rb | 10 +++- app/models/retainer_deliverable.rb | 13 +++++ app/views/deliverables/_details_row.html.erb | 4 +- test/integration/contracts_show_test.rb | 34 +++++++++++ test/unit/retainer_deliverable_test.rb | 60 ++++++++++++++++++++ 6 files changed, 129 insertions(+), 3 deletions(-) diff --git a/app/models/deliverable.rb b/app/models/deliverable.rb index e6db222..6e7f49d 100644 --- a/app/models/deliverable.rb +++ b/app/models/deliverable.rb @@ -80,6 +80,10 @@ class Deliverable < ActiveRecord::Base labor_budgets.sum(:hours) end + def overhead_budget_hours(date=nil) + overhead_budgets.sum(:hours) + end + # Total number of hours estimated in the Deliverable's budgets def estimated_hour_budget_total (labor_budgets.sum(:hours) || 0.0) + @@ -90,7 +94,12 @@ class Deliverable < ActiveRecord::Base def labor_hours_spent_total(date=nil) issues.inject(0) {|total, issue| total += issue.billable_time_spent } # From redmine_overhead end - + + # OPTIMIZE: N+1 + def overhead_hours_spent_total(date=nil) + issues.inject(0) {|total, issue| total += issue.overhead_time_spent } # From redmine_overhead + end + # OPTIMIZE: N+1 def hours_spent_total issues.inject(0) {|total, issue| total += issue.spent_hours } diff --git a/app/models/hourly_deliverable.rb b/app/models/hourly_deliverable.rb index ffddb97..dbc452d 100644 --- a/app/models/hourly_deliverable.rb +++ b/app/models/hourly_deliverable.rb @@ -50,8 +50,16 @@ class HourlyDeliverable < Deliverable protected def billable_hours_on_time_entries(time_entries) + hours_on_time_entries_with_billable_option(true, time_entries) + end + + def nonbillable_hours_on_time_entries(time_entries) + hours_on_time_entries_with_billable_option(false, time_entries) + end + + def hours_on_time_entries_with_billable_option(billable, time_entries) time_entries.inject(0) {|total, time_entry| - total += time_entry.hours if time_entry.billable? + total += time_entry.hours if (time_entry.billable? == billable) total } end diff --git a/app/models/retainer_deliverable.rb b/app/models/retainer_deliverable.rb index 2237025..3cfb750 100644 --- a/app/models/retainer_deliverable.rb +++ b/app/models/retainer_deliverable.rb @@ -146,6 +146,19 @@ class RetainerDeliverable < HourlyDeliverable end end + def overhead_hours_spent_total(date=nil) + case scope_date_status(date) + when :in + time_entries = issues.collect {|issue| issue.time_entries.all(:conditions => {:tyear => date.year, :tmonth => date.month}) }.flatten + + nonbillable_hours_on_time_entries(time_entries) + when :out + 0 + else + super + end + end + def fixed_budget_total(date=nil) case scope_date_status(date) when :in diff --git a/app/views/deliverables/_details_row.html.erb b/app/views/deliverables/_details_row.html.erb index 856c7b6..eb8925c 100644 --- a/app/views/deliverables/_details_row.html.erb +++ b/app/views/deliverables/_details_row.html.erb @@ -62,7 +62,9 @@ Overhead <%= h(format_value_field_for_contracts(deliverable.overhead_spent(validated_period))) %> <%= h(format_value_field_for_contracts(deliverable.overhead_budget_total(validated_period))) %> - TODO: Release 2 / TODO hrs + + <%= h(format_value_field_for_contracts(deliverable.overhead_hours_spent_total(validated_period))) %>/<%= h(format_value_field_for_contracts(deliverable.overhead_budget_hours(validated_period))) %> <%= l(:text_short_hours) %> + <% deliverable.fixed_budgets.by_period(validated_period).each do |fixed_budget| %> diff --git a/test/integration/contracts_show_test.rb b/test/integration/contracts_show_test.rb index 101c422..48d7387 100644 --- a/test/integration/contracts_show_test.rb +++ b/test/integration/contracts_show_test.rb @@ -315,6 +315,40 @@ class ContractsShowTest < ActionController::IntegrationTest end + should "show the overhead hours for the deliverable" do + configure_overhead_plugin + + @manager = User.generate! + + @deliverable1 = FixedDeliverable.generate!(:contract => @contract, :manager => @manager) + OverheadBudget.generate!(:deliverable => @deliverable1, + :hours => 100, + :budget => 4000.5) + + @issue1 = Issue.generate_for_project!(@project) + @time_entry1 = TimeEntry.generate!(:issue => @issue1, + :project => @project, + :activity => @non_billable_activity, + :spent_on => Date.today, + :hours => 5, + :user => @manager) + + @rate = Rate.generate!(:project => @project, + :user => @manager, + :date_in_effect => Date.yesterday, + :amount => 100) + + @deliverable1.issues << @issue1 + + assert_equal 1, @deliverable1.issues.count + + visit_contract_page(@contract) + assert_select "table#deliverables" do + assert_select "td.overhead_hours", :text => /5\/100/ + end + + end + should "show the current period for a Retainer" do today_mock = Date.new(2010,2,15) Date.stubs(:today).returns(today_mock) diff --git a/test/unit/retainer_deliverable_test.rb b/test/unit/retainer_deliverable_test.rb index 860b0da..f3e68c3 100644 --- a/test/unit/retainer_deliverable_test.rb +++ b/test/unit/retainer_deliverable_test.rb @@ -236,6 +236,66 @@ class RetainerDeliverableTest < ActiveSupport::TestCase end end + context "#overhead_hours_spent_total" do + setup do + @project = Project.generate! + @contract = Contract.generate!(:billable_rate => 100, :project => @project) + @deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract) + + @manager = User.generate! + @role = Role.generate! + User.add_to_project(@manager, @project, @role) + + configure_overhead_plugin + + @issue1 = Issue.generate_for_project!(@project) + @time_entry1 = TimeEntry.generate!(:issue => @issue1, + :project => @project, + :activity => @non_billable_activity, + :spent_on => Date.new(2010,1,2), + :hours => 10, + :user => @manager) + @time_entry2 = TimeEntry.generate!(:issue => @issue1, + :project => @project, + :activity => @non_billable_activity, + :spent_on => Date.new(2010,2,1), + :hours => 20, + :user => @manager) + + @rate = Rate.generate!(:project => @project, + :user => @manager, + :date_in_effect => Date.new(2010,1,1), + :amount => 100) + + @deliverable.issues << @issue1 + assert_equal 30, @deliverable.overhead_hours_spent_total + end + + context "with a empty period" do + should "use all periods" do + assert_equal 30.0, @deliverable.overhead_hours_spent_total(nil) + end + end + + context "with a period out of the retainer range" do + should "filter the records" do + assert_equal 0, @deliverable.overhead_hours_spent_total(Date.new(2011,1,1)) + end + end + + context "with an invalid period" do + should "return 0" do + assert_equal 0, @deliverable.overhead_hours_spent_total('1') + end + end + + context "with a period in the retainer range" do + should "filter the records" do + assert_equal 20.0, @deliverable.overhead_hours_spent_total(Date.new(2010,2,1)) + end + end + end + context "#overhead_spent" do setup do @project = Project.generate!