WIP: working on getting the report to work for periods
This commit is contained in:
+22
-10
@@ -279,32 +279,44 @@ class Deliverable < ActiveRecord::Base
|
||||
end
|
||||
|
||||
# Total amount spent ($) for a given activity
|
||||
def spent_for_activity(activity)
|
||||
def spent_for_activity(activity, options={})
|
||||
period = options[:period] || nil
|
||||
issues.all.inject(0.0) do |all_issues_total, issue|
|
||||
all_issues_total += issue.time_entries.all(:conditions => {:activity_id => activity.id}).sum(&:cost)
|
||||
conditions = ARCondition.new(["activity_id IN (?)", activity.id])
|
||||
if period.present?
|
||||
conditions.add(["tyear = ? AND tmonth = ?", period.year, period.month])
|
||||
end
|
||||
all_issues_total += issue.time_entries.all(:conditions => conditions.conditions).sum(&:cost)
|
||||
all_issues_total
|
||||
end
|
||||
end
|
||||
|
||||
# Total hours spent for a given activity
|
||||
def hours_spent_for_activity(activity)
|
||||
def hours_spent_for_activity(activity, options={})
|
||||
issue_ids = issues.collect(&:id)
|
||||
TimeEntry.sum(:hours,
|
||||
:conditions => ["#{TimeEntry.table_name}.issue_id IN (?) AND activity_id IN (?)", issue_ids, activity.id])
|
||||
end
|
||||
|
||||
# Total budget ($) for a given activity
|
||||
def budget_for_activity(activity)
|
||||
labor = labor_budgets.sum(:budget,
|
||||
:conditions => ["#{LaborBudget.table_name}.time_entry_activity_id IN (?)", activity.id])
|
||||
overhead = overhead_budgets.sum(:budget,
|
||||
:conditions => ["#{OverheadBudget.table_name}.time_entry_activity_id IN (?)", activity.id])
|
||||
|
||||
def budget_for_activity(activity, options={})
|
||||
period = options[:period] || nil
|
||||
labor_conditions = ARCondition.new(["#{LaborBudget.table_name}.time_entry_activity_id IN (?)", activity.id])
|
||||
overhead_conditions = ARCondition.new(["#{OverheadBudget.table_name}.time_entry_activity_id IN (?)", activity.id])
|
||||
if period.present?
|
||||
labor_conditions.add(["#{LaborBudget.table_name}.year = ?", period.year])
|
||||
labor_conditions.add(["#{LaborBudget.table_name}.month = ?", period.month])
|
||||
overhead_conditions.add(["#{OverheadBudget.table_name}.year = ?", period.year])
|
||||
overhead_conditions.add(["#{OverheadBudget.table_name}.month = ?", period.month])
|
||||
end
|
||||
|
||||
labor = labor_budgets.sum(:budget, :conditions => labor_conditions.conditions)
|
||||
overhead = overhead_budgets.sum(:budget, :conditions => overhead_conditions.conditions)
|
||||
labor.to_f + overhead.to_f
|
||||
end
|
||||
|
||||
# Total budget (hours) a given activity
|
||||
def hours_budget_for_activity(activity)
|
||||
def hours_budget_for_activity(activity, options={})
|
||||
labor = labor_budgets.sum(:hours,
|
||||
:conditions => ["#{LaborBudget.table_name}.time_entry_activity_id IN (?)", activity.id])
|
||||
overhead = overhead_budgets.sum(:hours,
|
||||
|
||||
@@ -37,17 +37,17 @@
|
||||
<td class="">
|
||||
<%= h(activity.name) %>
|
||||
</td>
|
||||
<td class="financial spent-amount <%= overage_class(deliverable.spent_for_activity(activity), deliverable.budget_for_activity(activity)) %>">
|
||||
<%= number_to_currency(deliverable.spent_for_activity(activity), :precision => Deliverable::ViewPrecision) %>
|
||||
<td class="financial spent-amount <%= overage_class(deliverable.spent_for_activity(activity, :period => period), deliverable.budget_for_activity(activity, :period => period)) %>">
|
||||
<%= number_to_currency(deliverable.spent_for_activity(activity, :period => period), :precision => Deliverable::ViewPrecision) %>
|
||||
</td>
|
||||
<td class="financial total-amount">
|
||||
<%= number_to_currency(deliverable.budget_for_activity(activity), :precision => Deliverable::ViewPrecision) %>
|
||||
<%= number_to_currency(deliverable.budget_for_activity(activity, :period => period), :precision => Deliverable::ViewPrecision) %>
|
||||
</td>
|
||||
<td class="numeric spent-hours <%= overage_class(deliverable.hours_spent_for_activity(activity), deliverable.hours_budget_for_activity(activity)) %>">
|
||||
<%= number_with_precision(deliverable.hours_spent_for_activity(activity), :precision => Deliverable::ViewPrecision) %>
|
||||
<td class="numeric spent-hours <%= overage_class(deliverable.hours_spent_for_activity(activity, :period => period), deliverable.hours_budget_for_activity(activity, :period => period)) %>">
|
||||
<%= number_with_precision(deliverable.hours_spent_for_activity(activity, :period => period), :precision => Deliverable::ViewPrecision) %>
|
||||
</td>
|
||||
<td class="numeric total-deliverable-hours">
|
||||
<%= number_with_precision(deliverable.hours_budget_for_activity(activity), :precision => Deliverable::ViewPrecision) %>
|
||||
<%= number_with_precision(deliverable.hours_budget_for_activity(activity, :period => period), :precision => Deliverable::ViewPrecision) %>
|
||||
</td>
|
||||
<% end %>
|
||||
|
||||
@@ -87,17 +87,17 @@
|
||||
<td class="">
|
||||
<%= h(activity.name) %>
|
||||
</td>
|
||||
<td class="financial spent-amount <%= overage_class(deliverable.spent_for_activity(activity), deliverable.budget_for_activity(activity)) %>">
|
||||
<%= number_to_currency(deliverable.spent_for_activity(activity), :precision => Deliverable::ViewPrecision) %>
|
||||
<td class="financial spent-amount <%= overage_class(deliverable.spent_for_activity(activity, :period => period), deliverable.budget_for_activity(activity, :period => period)) %>">
|
||||
<%= number_to_currency(deliverable.spent_for_activity(activity, :period => period), :precision => Deliverable::ViewPrecision) %>
|
||||
</td>
|
||||
<td class="financial total-amount">
|
||||
<%= number_to_currency(deliverable.budget_for_activity(activity), :precision => Deliverable::ViewPrecision) %>
|
||||
<%= number_to_currency(deliverable.budget_for_activity(activity, :period => period), :precision => Deliverable::ViewPrecision) %>
|
||||
</td>
|
||||
<td class="numeric spent-hours <%= overage_class(deliverable.hours_spent_for_activity(activity), deliverable.hours_budget_for_activity(activity)) %>">
|
||||
<%= number_with_precision(deliverable.hours_spent_for_activity(activity), :precision => Deliverable::ViewPrecision) %>
|
||||
<td class="numeric spent-hours <%= overage_class(deliverable.hours_spent_for_activity(activity, :period => period), deliverable.hours_budget_for_activity(activity, :period => period)) %>">
|
||||
<%= number_with_precision(deliverable.hours_spent_for_activity(activity, :period => period), :precision => Deliverable::ViewPrecision) %>
|
||||
</td>
|
||||
<td class="numeric total-deliverable-hours">
|
||||
<%= number_with_precision(deliverable.hours_budget_for_activity(activity), :precision => Deliverable::ViewPrecision) %>
|
||||
<%= number_with_precision(deliverable.hours_budget_for_activity(activity, :period => period), :precision => Deliverable::ViewPrecision) %>
|
||||
</td>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -205,4 +205,92 @@ class DeliverableFinancesShowTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "for a request for a different period" do
|
||||
setup do
|
||||
@period = "2010-02"
|
||||
visit "/projects/#{@project.id}/contracts/#{@contract.id}/deliverables/#{@deliverable1.id}/finances?period=#{@period}"
|
||||
|
||||
assert_response :success
|
||||
|
||||
# All work done in setup() is past this period, only these items should show up.
|
||||
Rate.generate!(:project => @deliverable1.project,
|
||||
:user => @manager,
|
||||
:date_in_effect => Date.new(2010, 2, 15),
|
||||
:amount => 45)
|
||||
# 2 hours of $45 billable work
|
||||
create_issue_with_time_for_deliverable(@deliverable1, {
|
||||
:activity => @billable_activity,
|
||||
:user => @manager,
|
||||
:hours => 2,
|
||||
:spent_on => Date.new(2010, 2,15),
|
||||
:skip_rate => true,
|
||||
:issue_category => @category_on_billable
|
||||
})
|
||||
# 1 hour of $45 billable work with no category
|
||||
create_issue_with_time_for_deliverable(@deliverable1, {
|
||||
:activity => @billable_activity,
|
||||
:user => @manager,
|
||||
:hours => 1,
|
||||
:spent_on => Date.new(2010, 2,15),
|
||||
:skip_rate => true,
|
||||
:issue_category => nil
|
||||
})
|
||||
# 3 hours of $45 nonbillable work
|
||||
create_issue_with_time_for_deliverable(@deliverable1, {
|
||||
:activity => @non_billable_activity,
|
||||
:user => @manager,
|
||||
:hours => 3,
|
||||
:spent_on => Date.new(2010, 2, 15),
|
||||
:skip_rate => true,
|
||||
:issue_category => @category_on_non_billable
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
should "calculate activity values based on the period only" do
|
||||
# Labor
|
||||
assert_select "table#deliverable-labor-activities" do
|
||||
assert_select "tr.labor" do
|
||||
assert_select "td", :text => /#{@billable_activity.name}/
|
||||
assert_select "td.spent-amount", :text => /\$135/ # 3 * $45
|
||||
assert_select "td.total-amount", :text => /\$100/ # 1 month
|
||||
assert_select "td.spent-hours", :text => /3/
|
||||
assert_select "td.total-deliverable-hours", :text => /10/ # 1 month
|
||||
end
|
||||
|
||||
assert_select "tr.summary-row.labor" do
|
||||
assert_select "td", :text => /Totals/
|
||||
assert_select "td.spent-amount", :text => /\$135/
|
||||
assert_select "td.total-amount", :text => /\$100/
|
||||
assert_select "td.spent-hours", :text => /3/
|
||||
assert_select "td.total-deliverable-hours", :text => /10/
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Overhead
|
||||
assert_select "table#deliverable-overhead-activities" do
|
||||
assert_select "tr.overhead" do
|
||||
assert_select "td", :text => /#{@non_billable_activity.name}/
|
||||
assert_select "td.spent-amount", :text => /\$135/
|
||||
assert_select "td.total-amount", :text => /\$200/
|
||||
assert_select "td.spent-hours", :text => /3/
|
||||
assert_select "td.total-deliverable-hours", :text => /10/ # 3 month retainer * 10
|
||||
end
|
||||
|
||||
assert_select "tr.summary-row.overhead" do
|
||||
assert_select "td", :text => /Totals/
|
||||
assert_select "td.spent-amount", :text => /\$135/
|
||||
assert_select "td.total-amount", :text => /\$200/
|
||||
assert_select "td.spent-hours", :text => /5/
|
||||
assert_select "td.total-deliverable-hours", :text => /10/
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
should "calculate user values based on the period only"
|
||||
should "calculate issue category values based on the period only"
|
||||
end
|
||||
end
|
||||
|
||||
+4
-2
@@ -131,18 +131,20 @@ class ActiveSupport::TestCase
|
||||
amount = options[:amount] || 100
|
||||
hours = options[:hours] || 2
|
||||
issue_category = options[:issue_category]
|
||||
skip_rate = options[:skip_rate] || false
|
||||
spent_on = options[:spent_on] || Date.today
|
||||
|
||||
issue = Issue.generate_for_project!(project, :category_id => issue_category.try(:id))
|
||||
time_entry = TimeEntry.generate!(:issue => issue,
|
||||
:project => project,
|
||||
:activity => activity,
|
||||
:spent_on => Date.today,
|
||||
:spent_on => spent_on,
|
||||
:hours => hours,
|
||||
:user => user)
|
||||
rate = Rate.generate!(:project => project,
|
||||
:user => user,
|
||||
:date_in_effect => Date.yesterday,
|
||||
:amount => amount)
|
||||
:amount => amount) unless skip_rate
|
||||
deliverable.issues << issue
|
||||
issue
|
||||
end
|
||||
|
||||
@@ -141,6 +141,31 @@ class DeliverableTest < ActiveSupport::TestCase
|
||||
|
||||
assert_equal 500.0, @deliverable.spent_for_activity(@billable_activity).to_f
|
||||
end
|
||||
|
||||
should "return the total amount spent for an activity during the period" do
|
||||
configure_overhead_plugin
|
||||
create_contract_and_deliverable
|
||||
Rate.generate!(:project => @deliverable.project,
|
||||
:user => @manager,
|
||||
:date_in_effect => Date.new(2010, 2, 15),
|
||||
:amount => 45)
|
||||
create_issue_with_time_for_deliverable(@deliverable, {
|
||||
:activity => @billable_activity,
|
||||
:user => @manager,
|
||||
:hours => 5,
|
||||
:amount => 100
|
||||
})
|
||||
create_issue_with_time_for_deliverable(@deliverable, {
|
||||
:activity => @billable_activity,
|
||||
:user => @manager,
|
||||
:hours => 2,
|
||||
:spent_on => Date.new(2010, 2,15),
|
||||
:skip_rate => true,
|
||||
:issue_category => @category_on_billable
|
||||
})
|
||||
|
||||
assert_equal 90.0, @deliverable.spent_for_activity(@billable_activity, :period => Date.new(2010,2,1)).to_f
|
||||
end
|
||||
end
|
||||
|
||||
context "#budget_for_activity" do
|
||||
@@ -153,7 +178,17 @@ class DeliverableTest < ActiveSupport::TestCase
|
||||
|
||||
assert_equal 600.0, @deliverable.budget_for_activity(@billable_activity).to_f # 200 * 3 months (retainer)
|
||||
end
|
||||
|
||||
|
||||
should "return the total amount budgeted for an activity during the period" do
|
||||
configure_overhead_plugin
|
||||
create_contract_and_deliverable
|
||||
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10, :time_entry_activity => @billable_activity)
|
||||
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10, :time_entry_activity => @billable_activity)
|
||||
@deliverable.save!
|
||||
|
||||
assert_equal 200.0, @deliverable.budget_for_activity(@billable_activity, :period => Date.new(2010,2,1)).to_f # 200 * 1 months (retainer)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "#hours_spent_for_activity" do
|
||||
@@ -170,7 +205,8 @@ class DeliverableTest < ActiveSupport::TestCase
|
||||
assert_equal 5.0, @deliverable.hours_spent_for_activity(@billable_activity).to_f
|
||||
|
||||
end
|
||||
|
||||
|
||||
should "return the total hours spent for an activity during the period"
|
||||
end
|
||||
|
||||
context "#hours_budget_for_activity" do
|
||||
@@ -183,7 +219,8 @@ class DeliverableTest < ActiveSupport::TestCase
|
||||
|
||||
assert_equal 60.0, @deliverable.hours_budget_for_activity(@billable_activity).to_f # 20 * 3 months (retainer)
|
||||
end
|
||||
|
||||
|
||||
should "return the total hours budgeted for an activity during the period" do
|
||||
end
|
||||
|
||||
context "#users_with_billable_time" do
|
||||
|
||||
Reference in New Issue
Block a user