diff --git a/app/models/budget.rb b/app/models/budget.rb index f128879..2347c96 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -33,20 +33,38 @@ class Budget return self.project.deliverables end + def budget + return self.deliverables.collect(&:budget).inject { |sum, n| sum + n} + end + + def budget_ratio + return ((self.spent / self.budget) * 100).round + end + # TODO def spent + 0 end - # TODO def left + return self.budget - self.spent end - # TODO def progress + return 100 unless self.deliverables.size > 0 + + balance = 0.0 + + self.deliverables.each do |deliverable| + balance += deliverable.budget * deliverable.progress + end + + return (balance / self.budget).round end # TODO def score + return self.progress - self.budget_ratio end # TODO diff --git a/spec/models/budget_spec.rb b/spec/models/budget_spec.rb index ac6fc15..b8a685c 100644 --- a/spec/models/budget_spec.rb +++ b/spec/models/budget_spec.rb @@ -164,3 +164,80 @@ describe Budget, '.final_due_date' do end end + +describe Budget, '.progress' do + it 'should be the weighted average by the deliverable progress and budget' do + @deliverable1 = mock_model(Deliverable, :project_id => @project, :budget => 2000.00, :progress => 50) + @deliverable2 = mock_model(Deliverable, :project_id => @project, :budget => 3000.00, :progress => 75) + + @project = mock_model(Project) + @project.stub!(:deliverables).and_return([@deliverable1, @deliverable2]) + Project.stub!(:find).with(@project.id).and_return(@project) + + @budget = Budget.new(@project.id) + @budget.progress.should eql(65) + end + + it 'should return 100 if there are no deliverables' do + @project = mock_model(Project) + @project.stub!(:deliverables).and_return([]) + Project.stub!(:find).with(@project.id).and_return(@project) + + @budget = Budget.new(@project.id) + @budget.progress.should eql(100) + end +end + +describe Budget,'.budget' do + it 'should be the sum of all the deliverables budget' do + @deliverable1 = mock_model(Deliverable, :project_id => @project, :budget => 2000.00) + @deliverable2 = mock_model(Deliverable, :project_id => @project, :budget => 3000.00) + + @project = mock_model(Project) + @project.stub!(:deliverables).and_return([@deliverable1, @deliverable2]) + Project.stub!(:find).with(@project.id).and_return(@project) + + @budget = Budget.new(@project.id) + @budget.budget.should eql(5000.0) + end +end + +describe Budget,'.budget_ratio' do + it 'should be the whole number of the budget spent (out of 100)' do + + @project = mock_model(Project) + Project.stub!(:find).with(@project.id).and_return(@project) + + @budget = Budget.new(@project.id) + @budget.should_receive(:budget).and_return(5000.00) + @budget.should_receive(:spent).and_return(2000.00) + @budget.budget_ratio.should eql(40) + end +end + + +describe Budget, '.score' do + it 'should be calculated by the progress and budget for the deliverables' do + @project = mock_model(Project) + Project.stub!(:find).with(@project.id).and_return(@project) + + @budget = Budget.new(@project.id) + @budget.should_receive(:progress).and_return(65) + @budget.should_receive(:budget_ratio).and_return(40) + + @budget.score.should eql(25) + end +end + +describe Budget, '.left' do + it 'should be calculated by the total budget and total spent of the deliverables' do + @project = mock_model(Project) + Project.stub!(:find).with(@project.id).and_return(@project) + + @budget = Budget.new(@project.id) + @budget.should_receive(:budget).and_return(6000.0) + @budget.should_receive(:spent).and_return(4500.0) + + @budget.left.should eql(1500.0) + end +end