Files
redmine_contracts/test/unit/retainer_deliverable_test.rb

810 lines
28 KiB
Ruby

require File.dirname(__FILE__) + '/../test_helper'
class RetainerDeliverableTest < ActiveSupport::TestCase
should "be a subclass of HourlyDeliverable" do
assert_equal HourlyDeliverable, RetainerDeliverable.superclass
end
context "#months" do
should "be an array of months the Deliverable is active in" do
d = RetainerDeliverable.new(:start_date => Date.today.beginning_of_month,
:end_date => 6.months.from_now)
assert_equal 7, d.months.length # 6 months + current month
d.months.each do |month|
assert_kind_of Date, month
end
end
should "return an empty array if start_date is missing" do
d = RetainerDeliverable.new(:start_date => nil,
:end_date => 6.months.from_now)
assert_equal [], d.months
end
should "return an empty array if end_date is missing" do
d = RetainerDeliverable.new(:start_date => Date.today.beginning_of_month,
:end_date => nil)
assert_equal [], d.months
end
should "return an empty array if the start_date and end_date are reversed" do
d = RetainerDeliverable.new(:start_date => 6.months.from_now,
:end_date => Date.today.beginning_of_month)
assert_equal [], d.months
end
end
context "#create_budgets_for_periods" do
setup do
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-10',
:end_date => '2010-10-10')
LaborBudget.generate!(:deliverable => @deliverable)
OverheadBudget.generate!(:deliverable => @deliverable)
OverheadBudget.generate!(:deliverable => @deliverable)
end
should "create a dated labor budget for each month" do
assert_equal 1, @deliverable.labor_budgets.count
@deliverable.reload.create_budgets_for_periods
assert_equal 10, @deliverable.labor_budgets.count
labor_budgets = @deliverable.labor_budgets
labor_budgets.each do |budget|
assert_equal 2010, budget.year
end
(1..10).each do |month_number|
assert_equal 1, labor_budgets.select {|b| b.month == month_number}.length
end
end
should "create a dated overhead budget for each month" do
assert_equal 2, @deliverable.overhead_budgets.count
@deliverable.reload.create_budgets_for_periods
assert_equal 20, @deliverable.overhead_budgets.count
overhead_budgets = @deliverable.overhead_budgets
overhead_budgets.each do |budget|
assert_equal 2010, budget.year
end
(1..10).each do |month_number|
assert_equal 2, overhead_budgets.select {|b| b.month == month_number}.length
end
end
end
context "#labor_budget_spent" 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)
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10)
@deliverable.overhead_budgets << OverheadBudget.spawn(:budget => 100, :hours => 10)
@deliverable.save!
@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 => @billable_activity,
:spent_on => Date.new(2010,1,2),
:hours => 10,
:user => @manager)
@time_entry2 = TimeEntry.generate!(:issue => @issue1,
:project => @project,
:activity => @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
end
context "with a empty period" do
should "use all periods" do
assert_equal (10+20) * 100, @deliverable.labor_budget_spent(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records periods" do
assert_equal 0, @deliverable.labor_budget_spent(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.labor_budget_spent('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 20 * 100, @deliverable.labor_budget_spent(Date.new(2010,2,1))
end
end
end
context "#labor_budget_total" do
setup do
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31')
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10)
@deliverable.save!
end
context "with a empty period" do
should "use all periods" do
assert_equal 300.0, @deliverable.labor_budget_total(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records" do
assert_equal 0, @deliverable.labor_budget_total(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.labor_budget_total('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 100.0, @deliverable.labor_budget_total(Date.new(2010,2,1))
end
end
end
context "#labor_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 => @billable_activity,
:spent_on => Date.new(2010,1,2),
:hours => 10,
:user => @manager)
@time_entry2 = TimeEntry.generate!(:issue => @issue1,
:project => @project,
:activity => @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.labor_hours_spent_total
end
context "with a empty period" do
should "use all periods" do
assert_equal 30.0, @deliverable.labor_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.labor_hours_spent_total(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.labor_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.labor_hours_spent_total(Date.new(2010,2,1))
end
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 "#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 => @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.hours_spent_total
end
context "with a empty period" do
should "use all periods" do
assert_equal 30.0, @deliverable.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.hours_spent_total(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.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.hours_spent_total(Date.new(2010,2,1))
end
end
end
context "#overhead_spent" 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)
@deliverable.overhead_budgets << OverheadBudget.spawn(:budget => 100, :hours => 10)
@deliverable.save!
@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
end
context "with a empty period" do
should "use all periods" do
assert_equal (10+20) * 100, @deliverable.overhead_spent(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records periods" do
assert_equal 0, @deliverable.overhead_spent(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.overhead_spent('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 20 * 100, @deliverable.overhead_spent(Date.new(2010,2,1))
end
end
end
context "#overhead_budget_total" do
setup do
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31')
@deliverable.overhead_budgets << OverheadBudget.spawn(:budget => 100, :hours => 10)
@deliverable.save!
end
context "with a empty period" do
should "use all periods" do
assert_equal 300.0, @deliverable.overhead_budget_total(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records" do
assert_equal 0, @deliverable.overhead_budget_total(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.overhead_budget_total('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 100.0, @deliverable.overhead_budget_total(Date.new(2010,2,1))
end
end
end
# (Labor used * contract rate) - (labor used * time rate) - (overhead used * time rate)
context "#profit_left" do
setup do
@project = Project.generate!
@contract = Contract.generate!(:billable_rate => 200, :project => @project)
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract)
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10)
@deliverable.overhead_budgets << OverheadBudget.spawn(:budget => 100, :hours => 10)
@deliverable.save!
@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 => @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
end
context "with a empty period" do
should "use all periods" do
assert_equal (10 * 200) - (10 * 100) - (20 * 100), @deliverable.profit_left(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records periods" do
assert_equal 0, @deliverable.profit_left(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.profit_left('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal (0 * 200) - (0 * 100) - (20 * 100), @deliverable.profit_left(Date.new(2010,2,1))
end
end
end
context "#profit_budget" do
setup do
@contract = Contract.generate!(:billable_rate => 100)
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract)
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10)
@deliverable.overhead_budgets << OverheadBudget.spawn(:budget => 100, :hours => 10)
@deliverable.save!
assert_equal 100 * 30, @deliverable.total
assert_equal 2400, @deliverable.profit_budget # 3000 - 300 - 300
end
context "with a empty period" do
should "use all periods" do
assert_equal 2400, @deliverable.profit_budget(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records" do
assert_equal 0, @deliverable.profit_budget(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.profit_budget('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 1000 - 200, @deliverable.profit_budget(Date.new(2010,2,1))
end
end
end
context "#total_spent" do
setup do
@project = Project.generate!
@contract = Contract.generate!(:billable_rate => 200, :project => @project)
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract)
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10)
@deliverable.overhead_budgets << OverheadBudget.spawn(:budget => 100, :hours => 10)
# Only paid fixed budgets counted
@deliverable.fixed_budgets << FixedBudget.generate!(:budget => '$100', :markup => '50%') # $50 markup
@deliverable.fixed_budgets << FixedBudget.generate!(:budget => '$100', :markup => '50%', :paid => true) # $50 markup
@deliverable.save!
@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 => @billable_activity,
:spent_on => Date.new(2010,1,2),
:hours => 10,
:user => @manager)
@time_entry2 = TimeEntry.generate!(:issue => @issue1,
:project => @project,
:activity => @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
end
context "with a empty period" do
should "use all periods" do
# (Labor used * contract rate) + fixed
assert_equal ((10+20) * 200) + (150 * 3), @deliverable.total_spent(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records periods" do
assert_equal 0, @deliverable.total_spent(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.total_spent('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal (20 * 200) + 150, @deliverable.total_spent(Date.new(2010,2,1))
end
end
end
context "#total" do
setup do
@contract = Contract.generate!(:billable_rate => 100)
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract)
@deliverable.labor_budgets << LaborBudget.spawn(:budget => 100, :hours => 10)
@deliverable.overhead_budgets << OverheadBudget.spawn(:budget => 100, :hours => 10)
@deliverable.save!
assert_equal 100 * 30, @deliverable.total
end
context "with a empty period" do
should "use all periods" do
assert_equal 3000, @deliverable.total(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records" do
assert_equal 0, @deliverable.total(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.total('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 1000, @deliverable.total(Date.new(2010,2,1))
end
end
end
context "#fixed_budget_total" do
setup do
@contract = Contract.generate!(:billable_rate => 100)
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract)
@deliverable.fixed_budgets << FixedBudget.spawn(:budget => 1000)
@deliverable.fixed_budgets << FixedBudget.spawn(:budget => 2000)
@deliverable.save!
assert_equal 3000 * 3, @deliverable.fixed_budget_total
end
context "with a empty period" do
should "use all periods" do
assert_equal 9000, @deliverable.fixed_budget_total(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records" do
assert_equal 0, @deliverable.fixed_budget_total(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.fixed_budget_total('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 3000, @deliverable.fixed_budget_total(Date.new(2010,2,1))
end
end
end
context "#fixed_budget_total_spent" do
setup do
@contract = Contract.generate!(:billable_rate => 100)
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract)
@deliverable.fixed_budgets << FixedBudget.spawn(:budget => 1000, :paid => true)
@deliverable.fixed_budgets << FixedBudget.spawn(:budget => 2000)
@deliverable.save!
assert_equal 1000 * 3, @deliverable.fixed_budget_total_spent
end
context "with a empty period" do
should "use all periods" do
assert_equal 3000, @deliverable.fixed_budget_total_spent(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records" do
assert_equal 0, @deliverable.fixed_budget_total_spent(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.fixed_budget_total_spent('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 1000, @deliverable.fixed_budget_total_spent(Date.new(2010,2,1))
end
end
end
context "#fixed_markup_budget_total" do
setup do
@contract = Contract.generate!(:billable_rate => 100)
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract)
@deliverable.fixed_budgets << FixedBudget.spawn(:budget => 1000, :markup => '50%')
@deliverable.fixed_budgets << FixedBudget.spawn(:budget => 2000, :markup => '$1000')
@deliverable.save!
assert_equal (500 + 1000) * 3, @deliverable.fixed_markup_budget_total
end
context "with a empty period" do
should "use all periods" do
assert_equal 4500, @deliverable.fixed_markup_budget_total(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records" do
assert_equal 0, @deliverable.fixed_markup_budget_total(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.fixed_markup_budget_total('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 1500, @deliverable.fixed_markup_budget_total(Date.new(2010,2,1))
end
end
end
context "#fixed_markup_budget_total_spent" do
setup do
@contract = Contract.generate!(:billable_rate => 100)
@deliverable = RetainerDeliverable.generate!(:start_date => '2010-01-01', :end_date => '2010-03-31', :contract => @contract)
@deliverable.fixed_budgets << FixedBudget.spawn(:budget => 1000, :markup => '50%', :paid => true)
@deliverable.fixed_budgets << FixedBudget.spawn(:budget => 2000, :markup => '$1000')
@deliverable.save!
assert_equal (500) * 3, @deliverable.fixed_markup_budget_total_spent
end
context "with a empty period" do
should "use all periods" do
assert_equal 1500, @deliverable.fixed_markup_budget_total_spent(nil)
end
end
context "with a period out of the retainer range" do
should "filter the records" do
assert_equal 0, @deliverable.fixed_markup_budget_total_spent(Date.new(2011,1,1))
end
end
context "with an invalid period" do
should "return 0" do
assert_equal 0, @deliverable.fixed_markup_budget_total_spent('1')
end
end
context "with a period in the retainer range" do
should "filter the records" do
assert_equal 500, @deliverable.fixed_markup_budget_total_spent(Date.new(2010,2,1))
end
end
end
end