diff --git a/app/models/deliverable.rb b/app/models/deliverable.rb index d832d69..1855c17 100644 --- a/app/models/deliverable.rb +++ b/app/models/deliverable.rb @@ -337,6 +337,27 @@ class Deliverable < ActiveRecord::Base end end + # Array of Issue Categories that have billable time logged + def issue_categories_with_billable_time + issue_categories_with_time(true) + end + + # Array of Issue Categories that have non-billable time logged + def issue_categories_with_non_billable_time + issue_categories_with_time(false) + end + + def issue_categories_with_time(billable_time_only) + time_entries = project.time_entries.all(:conditions => ["#{TimeEntry.table_name}.issue_id IN (?)", issue_ids]) + + time_entries.inject([]) do |categories, time_entry| + if time_entry.billable? == billable_time_only && time_entry.issue.present? && time_entry.issue.category.present? + categories << time_entry.issue.category unless categories.include?(time_entry.issue.category) + end + categories + end + end + def spent_for_user(user, billable_time_only) time_entries = project.time_entries.all(:conditions => ["#{TimeEntry.table_name}.issue_id IN (?) AND #{TimeEntry.table_name}.user_id IN (?)", issue_ids, user.id]) @@ -349,6 +370,18 @@ class Deliverable < ActiveRecord::Base time_entries.select {|time| time.billable? == billable_time_only }.sum(&:hours) end + def spent_for_issue_category(category, billable_time_only) + time_entries = project.time_entries.all(:conditions => ["#{TimeEntry.table_name}.issue_id IN (?) AND #{Issue.table_name}.category_id IN (?)", issue_ids, category.id], :include => [:issue]) + + time_entries.select {|time| time.billable? == billable_time_only }.sum(&:cost) + end + + def hours_spent_for_issue_category(category, billable_time_only) + time_entries = project.time_entries.all(:conditions => ["#{TimeEntry.table_name}.issue_id IN (?) AND #{Issue.table_name}.category_id IN (?)", issue_ids, category.id], :include => [:issue]) + + time_entries.select {|time| time.billable? == billable_time_only }.sum(&:hours) + end + def self.valid_types ['FixedDeliverable','HourlyDeliverable','RetainerDeliverable'] end diff --git a/test/test_helper.rb b/test/test_helper.rb index 8ce638b..5373422 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -130,8 +130,9 @@ class ActiveSupport::TestCase activity = options[:activity] amount = options[:amount] || 100 hours = options[:hours] || 2 + issue_category = options[:issue_category] - issue = Issue.generate_for_project!(project) + issue = Issue.generate_for_project!(project, :category_id => issue_category.try(:id)) time_entry = TimeEntry.generate!(:issue => issue, :project => project, :activity => activity, diff --git a/test/unit/deliverable_test.rb b/test/unit/deliverable_test.rb index 7835179..75ea378 100644 --- a/test/unit/deliverable_test.rb +++ b/test/unit/deliverable_test.rb @@ -318,4 +318,160 @@ class DeliverableTest < ActiveSupport::TestCase end end + + context "#issue_categories_with_billable_time" do + setup do + configure_overhead_plugin + create_contract_and_deliverable + @category_one = IssueCategory.generate!(:project => @project) + @category_two = IssueCategory.generate!(:project => @project) + + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @billable_activity, + :user => @manager, + :issue_category => @category_one + }) + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @non_billable_activity, + :user => @manager, + :issue_category => @category_one + }) + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @non_billable_activity, + :user => @manager, + :issue_category => @category_two + }) + + end + + should "include categories with billable Time Entries" do + assert @deliverable.issue_categories_with_billable_time.include?(@category_one) + end + + should "not include categories with only nonbillable Time Entries" do + assert !@deliverable.issue_categories_with_billable_time.include?(@category_two) + end + end + + context "#issue_categories_with_non_billable_time" do + setup do + configure_overhead_plugin + create_contract_and_deliverable + @category_one = IssueCategory.generate!(:project => @project) + @category_two = IssueCategory.generate!(:project => @project) + + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @non_billable_activity, + :user => @manager, + :issue_category => @category_one + }) + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @billable_activity, + :user => @manager, + :issue_category => @category_one + }) + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @billable_activity, + :user => @manager, + :issue_category => @category_two + }) + + end + + should "include categories with non-billable Time Entries" do + assert @deliverable.issue_categories_with_non_billable_time.include?(@category_one) + end + + should "not include categories with only billable Time Entries" do + assert !@deliverable.issue_categories_with_non_billable_time.include?(@category_two) + end + end + + context "#spent_for_issue_category" do + setup do + configure_overhead_plugin + create_contract_and_deliverable + @category_one = IssueCategory.generate!(:project => @project) + + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @billable_activity, + :user => @manager, + :hours => 5, + :amount => 100, + :issue_category => @category_one + }) + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @billable_activity, + :user => @manager, + :hours => 5, + :amount => 100, + :issue_category => @category_one + }) + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @non_billable_activity, + :user => @manager, + :hours => 5, + :amount => 100, + :issue_category => @category_one + }) + + end + + context "with billable_time_only as true" do + should "return the total cost the category has logged on billable time entries" do + assert_equal 1000, @deliverable.spent_for_issue_category(@category_one, true) + end + end + + context "with billable_time_only as false" do + should "return the total cost the category has logged on non-billable time entries" do + assert_equal 500, @deliverable.spent_for_issue_category(@category_one, false) + end + end + + end + + context "#hours_spent_for_issue_category" do + setup do + configure_overhead_plugin + create_contract_and_deliverable + @category_one = IssueCategory.generate!(:project => @project) + + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @billable_activity, + :user => @manager, + :hours => 5, + :amount => 100, + :issue_category => @category_one + }) + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @billable_activity, + :user => @manager, + :hours => 5, + :amount => 100, + :issue_category => @category_one + }) + create_issue_with_time_for_deliverable(@deliverable, { + :activity => @non_billable_activity, + :user => @manager, + :hours => 5, + :amount => 100, + :issue_category => @category_one + }) + + end + + context "with billable_time_only as true" do + should "return the total hours the category has logged on billable time entries" do + assert_equal 10, @deliverable.hours_spent_for_issue_category(@category_one, true) + end + end + + context "with billable_time_only as false" do + should "return the total hours the category has logged on non-billable time entries" do + assert_equal 5, @deliverable.hours_spent_for_issue_category(@category_one, false) + end + end + + end end