From dbfc6c5335f53453d7f5823b8f5f3b88034920f3 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Wed, 6 Oct 2010 12:12:45 -0700 Subject: [PATCH] [#4604] Add basic caching for TimeEntry#cost --- db/migrate/004_add_cost_to_time_entries.rb | 9 +++++ lib/rate_time_entry_patch.rb | 27 +++++++++++---- test/unit/lib/rate_time_entry_patch_test.rb | 38 ++++++++++++++++++++- 3 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 db/migrate/004_add_cost_to_time_entries.rb diff --git a/db/migrate/004_add_cost_to_time_entries.rb b/db/migrate/004_add_cost_to_time_entries.rb new file mode 100644 index 0000000..37ddca1 --- /dev/null +++ b/db/migrate/004_add_cost_to_time_entries.rb @@ -0,0 +1,9 @@ +class AddCostToTimeEntries < ActiveRecord::Migration + def self.up + add_column :time_entries, :cost, :decimal, :precision => 15, :scale => 2 + end + + def self.down + remove_column :time_entries, :cost + end +end diff --git a/lib/rate_time_entry_patch.rb b/lib/rate_time_entry_patch.rb index a625af2..2a7fa0f 100644 --- a/lib/rate_time_entry_patch.rb +++ b/lib/rate_time_entry_patch.rb @@ -20,15 +20,28 @@ module RateTimeEntryPatch module InstanceMethods # Returns the current cost of the TimeEntry based on it's rate and hours def cost - if self.rate.nil? - amount = Rate.amount_for(self.user, self.project, self.spent_on.to_s) - else - amount = rate.amount + unless @cost + if self.rate.nil? + amount = Rate.amount_for(self.user, self.project, self.spent_on.to_s) + else + amount = rate.amount + end + + if amount.nil? + @cost = 0.0 + else + @cost = amount.to_f * hours.to_f + end + + cache_cost end - return 0.0 if amount.nil? - - return amount.to_f * hours.to_f + @cost + end + + def cache_cost + @cost ||= cost + update_attribute(:cost, @cost) end end end diff --git a/test/unit/lib/rate_time_entry_patch_test.rb b/test/unit/lib/rate_time_entry_patch_test.rb index 1945ac7..10af714 100644 --- a/test/unit/lib/rate_time_entry_patch_test.rb +++ b/test/unit/lib/rate_time_entry_patch_test.rb @@ -5,7 +5,7 @@ class RateTimeEntryPatchTest < ActiveSupport::TestCase @user = User.generate! @project = Project.generate! @date = Date.today.to_s - @time_entry = TimeEntry.new({:user => @user, :project => @project, :spent_on => @date, :hours => 10.0}) + @time_entry = TimeEntry.new({:user => @user, :project => @project, :spent_on => @date, :hours => 10.0, :activity => TimeEntryActivity.generate!}) end should 'should return 0.0 if there are no rates for the user' do @@ -26,4 +26,40 @@ class RateTimeEntryPatchTest < ActiveSupport::TestCase end + context "#cost" do + setup do + @time_entry.save! + Rate.generate!(:user => @user, :project => @project, :date_in_effect => @date, :amount => 200.0) + end + + context "without a cache" do + should "return the calculated cost" do + @time_entry.update_attribute(:cost, nil) + assert_equal 2000.0, @time_entry.cost + end + + should "cache the cost to the field" do + @time_entry.update_attribute(:cost, nil) + @time_entry.cost + + assert_equal 2000.0, @time_entry.read_attribute(:cost) + assert_equal 2000.0, @time_entry.reload.read_attribute(:cost) + end + + end + + context "with a cache" do + setup do + @time_entry.cache_cost + end + + should "return the cached cost" do + assert_equal 2000.0, @time_entry.read_attribute(:cost) + assert_equal 2000.0, @time_entry.cost + end + + end + + end + end