Merge branch 'master' into local/4184-budget-migration
This commit is contained in:
+11
-6
@@ -38,12 +38,6 @@ class Contract < ActiveRecord::Base
|
||||
define_method(mthd) { "TODO in later release" }
|
||||
end
|
||||
|
||||
[:total_spent,
|
||||
:profit_spent
|
||||
].each do |mthd|
|
||||
define_method(mthd) { "TODO" }
|
||||
end
|
||||
|
||||
# OPTIMIZE: N+1
|
||||
def labor_budget
|
||||
deliverables.inject(0) {|total, deliverable| total += deliverable.labor_budget_total }
|
||||
@@ -81,11 +75,22 @@ class Contract < ActiveRecord::Base
|
||||
deliverables.inject(0) {|total, deliverable| total += deliverable.total }
|
||||
end
|
||||
|
||||
# OPTIMIZE: N+1
|
||||
def total_spent
|
||||
deliverables.inject(0) {|total, deliverable| total += deliverable.total_spent }
|
||||
end
|
||||
|
||||
# OPTIMIZE: N+1
|
||||
def profit_budget
|
||||
deliverables.inject(0) {|total, deliverable| total += deliverable.profit_budget }
|
||||
end
|
||||
|
||||
# OPTIMIZE: N+1
|
||||
def profit_left
|
||||
deliverables.inject(0) {|total, deliverable| total += deliverable.profit_left }
|
||||
end
|
||||
alias_method :profit_spent, :profit_left
|
||||
|
||||
PaymentTerms = {
|
||||
:net_0 => :text_payment_terms_net_0,
|
||||
:net_15 => :text_payment_terms_net_15,
|
||||
|
||||
@@ -15,12 +15,23 @@ class FixedDeliverable < Deliverable
|
||||
read_attribute(:total) || 0.0
|
||||
end
|
||||
|
||||
# Fixed deliverables are always 100% spent
|
||||
def total_spent
|
||||
total
|
||||
end
|
||||
|
||||
# The amount of profit that is budgeted for this deliverable.
|
||||
# Profit = Total - ( Labor + Overhead + Fixed + Markup )
|
||||
def profit_budget
|
||||
budgets = labor_budget_total + overhead_budget_total
|
||||
(total || 0.0) - budgets
|
||||
end
|
||||
|
||||
# The amount of money remaining after expenses have been taken out
|
||||
# Profit left = Total - Labor spent - Overhead spent
|
||||
def profit_left
|
||||
total_spent - labor_budget_spent - overhead_spent
|
||||
end
|
||||
|
||||
# Hardcoded value used as a wrapper for the old Budget plugin API.
|
||||
#
|
||||
|
||||
@@ -19,8 +19,23 @@ class HourlyDeliverable < Deliverable
|
||||
return 0 if contract.billable_rate.blank?
|
||||
return 0 if labor_budgets.count == 0 && overhead_budgets.count == 0
|
||||
|
||||
hours = labor_budgets.sum(:hours) + overhead_budgets.sum(:hours)
|
||||
return contract.billable_rate * hours
|
||||
return contract.billable_rate * labor_budgets.sum(:hours)
|
||||
end
|
||||
|
||||
# Total amount to be billed on the deliverable, using the total time logged
|
||||
# and the contract rate
|
||||
def total_spent
|
||||
return 0 if contract.nil?
|
||||
return 0 if contract.billable_rate.blank?
|
||||
return 0 unless self.issues.count > 0
|
||||
|
||||
time_logs = self.issues.collect(&:time_entries).flatten
|
||||
hours = time_logs.inject(0) {|total, time_entry|
|
||||
total += time_entry.hours if time_entry.billable?
|
||||
total
|
||||
}
|
||||
|
||||
return hours * contract.billable_rate
|
||||
end
|
||||
|
||||
# Block setting the total on HourlyDeliverables
|
||||
@@ -38,4 +53,10 @@ class HourlyDeliverable < Deliverable
|
||||
budgets = labor_budget_total + overhead_budget_total
|
||||
(total || 0.0) - budgets
|
||||
end
|
||||
|
||||
# The amount of money remaining after expenses have been taken out
|
||||
# Profit left = Total - Labor spent - Overhead spent
|
||||
def profit_left
|
||||
total_spent - labor_budget_spent - overhead_spent
|
||||
end
|
||||
end
|
||||
|
||||
@@ -163,7 +163,7 @@ class ContractTest < ActiveSupport::TestCase
|
||||
LaborBudget.generate!(:deliverable => @deliverable_2, :hours => 10)
|
||||
OverheadBudget.generate!(:deliverable => @deliverable_2, :hours => 20)
|
||||
|
||||
assert_equal 10_000 + (30 * 100), contract.total_budget
|
||||
assert_equal 10_000 + (10 * 100), contract.total_budget
|
||||
end
|
||||
end
|
||||
|
||||
@@ -180,9 +180,79 @@ class ContractTest < ActiveSupport::TestCase
|
||||
OverheadBudget.generate!(:deliverable => @deliverable_2, :hours => 20)
|
||||
|
||||
assert_equal 10_000 - 4000, @deliverable_1.profit_budget
|
||||
assert_equal (30 * 100.0) - 0, @deliverable_2.profit_budget
|
||||
assert_equal 9000, contract.profit_budget
|
||||
assert_equal (10 * 100.0) - 0, @deliverable_2.profit_budget
|
||||
assert_equal 7000, contract.profit_budget
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
context "#total_spent" do
|
||||
should "sum all of the total spents on the Deliverables" do
|
||||
configure_overhead_plugin
|
||||
|
||||
contract = Contract.generate!(:billable_rate => 150.0)
|
||||
|
||||
@project = Project.generate!
|
||||
@developer = User.generate!
|
||||
@role = Role.generate!
|
||||
User.add_to_project(@developer, @project, @role)
|
||||
|
||||
contract.deliverables << @deliverable_1 = FixedDeliverable.generate!(:total => 10_000)
|
||||
contract.deliverables << @deliverable_2 = HourlyDeliverable.generate!(:contract => contract)
|
||||
@deliverable_2.issues << @issue1 = Issue.generate_for_project!(@project)
|
||||
TimeEntry.generate!(:hours => 15, :issue => @issue1, :project => @project,
|
||||
:activity => @billable_activity,
|
||||
:user => @developer)
|
||||
|
||||
assert_equal 10_000, @deliverable_1.total_spent
|
||||
assert_equal 2250, @deliverable_2.total_spent
|
||||
assert_equal 12_250, contract.total_spent
|
||||
end
|
||||
end
|
||||
|
||||
context "#profit_left" do
|
||||
should "sum all of the profit left on all of the Deliverables" do
|
||||
configure_overhead_plugin
|
||||
|
||||
contract = Contract.generate!(:billable_rate => 150.0)
|
||||
|
||||
@project = Project.generate!
|
||||
@developer = User.generate!
|
||||
@manager = User.generate!
|
||||
@role = Role.generate!
|
||||
User.add_to_project(@developer, @project, @role)
|
||||
User.add_to_project(@manager, @project, @role)
|
||||
@rate = Rate.generate!(:project => @project,
|
||||
:user => @developer,
|
||||
:date_in_effect => Date.yesterday,
|
||||
:amount => 55)
|
||||
@rate = Rate.generate!(:project => @project,
|
||||
:user => @manager,
|
||||
:date_in_effect => Date.yesterday,
|
||||
:amount => 75)
|
||||
|
||||
contract.deliverables << @deliverable_1 = FixedDeliverable.generate!(:total => 2000)
|
||||
@deliverable_1.issues << @issue1 = Issue.generate_for_project!(@project)
|
||||
TimeEntry.generate!(:hours => 15, :issue => @issue1, :project => @project,
|
||||
:activity => @billable_activity,
|
||||
:user => @developer)
|
||||
TimeEntry.generate!(:hours => 4, :issue => @issue1, :project => @project,
|
||||
:activity => @non_billable_activity,
|
||||
:user => @manager)
|
||||
|
||||
contract.deliverables << @deliverable_2 = HourlyDeliverable.generate!(:contract => contract)
|
||||
@deliverable_2.issues << @issue2 = Issue.generate_for_project!(@project)
|
||||
TimeEntry.generate!(:hours => 15, :issue => @issue2, :project => @project,
|
||||
:activity => @billable_activity,
|
||||
:user => @developer)
|
||||
TimeEntry.generate!(:hours => 4, :issue => @issue2, :project => @project,
|
||||
:activity => @non_billable_activity,
|
||||
:user => @manager)
|
||||
|
||||
assert_equal 875, @deliverable_1.profit_left
|
||||
assert_equal 1125, @deliverable_2.profit_left
|
||||
assert_equal 2000, contract.profit_left
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,4 +21,47 @@ class FixedDeliverableTest < ActiveSupport::TestCase
|
||||
assert_equal 0, FixedDeliverable.generate(:total => nil).profit_budget
|
||||
end
|
||||
end
|
||||
|
||||
context "#total_spent" do
|
||||
should "equal the budgeted total" do
|
||||
assert_equal 1000, FixedDeliverable.generate(:total => 1_000).total_spent
|
||||
end
|
||||
end
|
||||
|
||||
context "#profit_left" do
|
||||
should "be the total_spent minus the labor budget spent minus the overhead budget spent" do
|
||||
configure_overhead_plugin
|
||||
|
||||
@project = Project.generate!
|
||||
@developer = User.generate!
|
||||
@manager = User.generate!
|
||||
@role = Role.generate!
|
||||
User.add_to_project(@developer, @project, @role)
|
||||
User.add_to_project(@manager, @project, @role)
|
||||
@rate = Rate.generate!(:project => @project,
|
||||
:user => @developer,
|
||||
:date_in_effect => Date.yesterday,
|
||||
:amount => 55)
|
||||
@rate = Rate.generate!(:project => @project,
|
||||
:user => @manager,
|
||||
:date_in_effect => Date.yesterday,
|
||||
:amount => 75)
|
||||
|
||||
@deliverable_1 = FixedDeliverable.generate!(:total => 2000)
|
||||
@deliverable_1.issues << @issue1 = Issue.generate_for_project!(@project)
|
||||
TimeEntry.generate!(:hours => 15, :issue => @issue1, :project => @project,
|
||||
:activity => @billable_activity,
|
||||
:user => @developer)
|
||||
TimeEntry.generate!(:hours => 4, :issue => @issue1, :project => @project,
|
||||
:activity => @non_billable_activity,
|
||||
:user => @manager)
|
||||
|
||||
# Check intermediate values
|
||||
assert_equal 825, @deliverable_1.labor_budget_spent
|
||||
assert_equal 300, @deliverable_1.overhead_spent
|
||||
|
||||
assert_equal 875, @deliverable_1.profit_left
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,13 +20,33 @@ class HourlyDeliverableTest < ActiveSupport::TestCase
|
||||
assert_equal 0, d.total
|
||||
end
|
||||
|
||||
should "multiply the total number of budgeted hours by the contract billable rate" do
|
||||
should "multiply the total number of labor budget hours by the contract billable rate" do
|
||||
contract = Contract.generate!(:billable_rate => 100.0)
|
||||
d = HourlyDeliverable.generate!(:contract => contract)
|
||||
d.labor_budgets << LaborBudget.generate!(:hours => 10)
|
||||
d.overhead_budgets << OverheadBudget.generate!(:hours => 20)
|
||||
|
||||
assert_equal 100.0 * 30, d.total
|
||||
assert_equal 100.0 * 10, d.total
|
||||
end
|
||||
end
|
||||
|
||||
context "#total_spent" do
|
||||
should "be equal to the number of hours used multipled by the contract rate" do
|
||||
configure_overhead_plugin
|
||||
|
||||
contract = Contract.generate!(:billable_rate => 150.0)
|
||||
@project = Project.generate!
|
||||
@developer = User.generate!
|
||||
@role = Role.generate!
|
||||
User.add_to_project(@developer, @project, @role)
|
||||
|
||||
d = HourlyDeliverable.generate!(:contract => contract)
|
||||
d.issues << @issue1 = Issue.generate_for_project!(@project)
|
||||
TimeEntry.generate!(:hours => 15, :issue => @issue1, :project => @project,
|
||||
:activity => @billable_activity,
|
||||
:user => @developer)
|
||||
|
||||
assert_equal 2250, d.total_spent
|
||||
end
|
||||
end
|
||||
|
||||
@@ -52,7 +72,7 @@ class HourlyDeliverableTest < ActiveSupport::TestCase
|
||||
|
||||
context "#profit_budget" do
|
||||
setup do
|
||||
@contract = Contract.generate!(:billable_rate => 100.0)
|
||||
@contract = Contract.generate!(:billable_rate => 150.0)
|
||||
@deliverable = HourlyDeliverable.generate!(:contract => @contract)
|
||||
end
|
||||
|
||||
@@ -63,12 +83,50 @@ class HourlyDeliverableTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
should "be the total minus the sum of all of the budgets' amounts" do
|
||||
LaborBudget.generate!(:deliverable => @deliverable, :hours => 10, :budget => 2000)
|
||||
LaborBudget.generate!(:deliverable => @deliverable, :hours => 5, :budget => 1000)
|
||||
OverheadBudget.generate!(:deliverable => @deliverable, :hours => 15, :budget => 2000)
|
||||
LaborBudget.generate!(:deliverable => @deliverable, :hours => 5, :budget => 250)
|
||||
LaborBudget.generate!(:deliverable => @deliverable, :hours => 5, :budget => 250)
|
||||
OverheadBudget.generate!(:deliverable => @deliverable, :hours => 3, :budget => 225)
|
||||
|
||||
assert_equal 30 * 100, @deliverable.total
|
||||
assert_equal 3000 - (2000 + 1000 + 2000), @deliverable.profit_budget
|
||||
assert_equal 1500, @deliverable.total
|
||||
assert_equal 1500 - (225 + 250 + 250), @deliverable.profit_budget
|
||||
end
|
||||
end
|
||||
|
||||
context "#profit_left" do
|
||||
should "be equal to the total to bill (total_spent) minus the labor budget spent minus the overhead spent" do
|
||||
configure_overhead_plugin
|
||||
|
||||
contract = Contract.generate!(:billable_rate => 150.0)
|
||||
@project = Project.generate!
|
||||
@developer = User.generate!
|
||||
@manager = User.generate!
|
||||
@role = Role.generate!
|
||||
User.add_to_project(@developer, @project, @role)
|
||||
User.add_to_project(@manager, @project, @role)
|
||||
@rate = Rate.generate!(:project => @project,
|
||||
:user => @developer,
|
||||
:date_in_effect => Date.yesterday,
|
||||
:amount => 55)
|
||||
@rate = Rate.generate!(:project => @project,
|
||||
:user => @manager,
|
||||
:date_in_effect => Date.yesterday,
|
||||
:amount => 75)
|
||||
|
||||
@deliverable_1 = HourlyDeliverable.generate!(:contract => contract)
|
||||
@deliverable_1.issues << @issue1 = Issue.generate_for_project!(@project)
|
||||
TimeEntry.generate!(:hours => 15, :issue => @issue1, :project => @project,
|
||||
:activity => @billable_activity,
|
||||
:user => @developer)
|
||||
TimeEntry.generate!(:hours => 4, :issue => @issue1, :project => @project,
|
||||
:activity => @non_billable_activity,
|
||||
:user => @manager)
|
||||
|
||||
# Check intermediate values
|
||||
assert_equal 825, @deliverable_1.labor_budget_spent
|
||||
assert_equal 300, @deliverable_1.overhead_spent
|
||||
|
||||
assert_equal 1125, @deliverable_1.profit_left
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user