Skip to content

Commit

Permalink
Drop @hours_in_interval instance variable on ChargebackRateDetail
Browse files Browse the repository at this point in the history
ChargebackRateDetail object should not know anything about some
interval. It should just maintain the logic to calculate the cost.

The @hours_in_interval is a function of given consumption slice.

Moreover, there is a problem with @hours_in_interval -- the interval can
be for instance one week, and the rate can be monthly, then we divide
monthly cost by week. B@ng!
  • Loading branch information
isimluk committed Jan 2, 2017
1 parent ae27ca5 commit 09cecec
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 18 deletions.
13 changes: 6 additions & 7 deletions app/models/chargeback_rate_detail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,25 +75,25 @@ def find_rate(value)
:yearly => "Year"
}

def hourly_cost(value)
def hourly_cost(value, consumption)
return 0.0 unless self.enabled?

value = 1.0 if fixed?

(fixed_rate, variable_rate) = find_rate(value)

hourly_fixed_rate = hourly(fixed_rate)
hourly_variable_rate = hourly(variable_rate)
hourly_fixed_rate = hourly(fixed_rate, consumption)
hourly_variable_rate = hourly(variable_rate, consumption)

hourly_fixed_rate + rate_adjustment(hourly_variable_rate) * value
end

def hourly(rate)
def hourly(rate, consumption)
hourly_rate = case per_time
when "hourly" then rate
when "daily" then rate / 24
when "weekly" then rate / 24 / 7
when "monthly" then rate / @hours_in_interval
when "monthly" then rate / consumption.hours_in_interval
when "yearly" then rate / 24 / 365
else raise "rate time unit of '#{per_time}' not supported"
end
Expand Down Expand Up @@ -223,9 +223,8 @@ def cost_keys
end

def metric_and_cost_by(consumption)
@hours_in_interval = consumption.hours_in_interval
metric_value = metric_value_by(consumption)
[metric_value, hourly_cost(metric_value) * consumption.hours_in_interval]
[metric_value, hourly_cost(metric_value, consumption) * consumption.hours_in_interval]
end

def first_tier?(tier,tiers)
Expand Down
19 changes: 8 additions & 11 deletions spec/models/chargeback_rate_detail_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
end

let(:hours_in_month) { 720 }
let(:consumption) { instance_double('Consumption', :hours_in_interval => hours_in_month) }

it '#hourly_cost' do
cvalue = 42.0
Expand All @@ -38,21 +39,20 @@
:per_time => per_time,
:per_unit => per_unit,
:enabled => true)
cbd.instance_variable_set(:@hours_in_interval, hours_in_month)
cbt = FactoryGirl.create(:chargeback_tier,
:chargeback_rate_detail_id => cbd.id,
:start => tier_start,
:finish => tier_finish,
:fixed_rate => fixed_rate,
:variable_rate => variable_rate)
cbd.update(:chargeback_tiers => [cbt])
expect(cbd.hourly_cost(cvalue)).to eq(cvalue * cbd.hourly(variable_rate) + cbd.hourly(fixed_rate))
expect(cbd.hourly_cost(cvalue, consumption)).to eq(cvalue * cbd.hourly(variable_rate, consumption) + cbd.hourly(fixed_rate, consumption))

cbd.group = 'fixed'
expect(cbd.hourly_cost(cvalue)).to eq(cbd.hourly(variable_rate) + cbd.hourly(fixed_rate))
expect(cbd.hourly_cost(cvalue, consumption)).to eq(cbd.hourly(variable_rate, consumption) + cbd.hourly(fixed_rate, consumption))

cbd.enabled = false
expect(cbd.hourly_cost(cvalue)).to eq(0.0)
expect(cbd.hourly_cost(cvalue, consumption)).to eq(0.0)
end

it "#hourly" do
Expand All @@ -63,7 +63,7 @@
].each do |rate|
cbd = FactoryGirl.build(:chargeback_rate_detail, :per_time => 'hourly')

expect(cbd.hourly(rate)).to eq(0.0)
expect(cbd.hourly(rate, consumption)).to eq(0.0)
end
cbdm = FactoryGirl.create(:chargeback_rate_detail_measure)
rate = 8.26
Expand All @@ -79,11 +79,10 @@
:per_unit => per_unit,
:metric => 'derived_memory_available',
:chargeback_rate_detail_measure_id => cbdm.id)
cbd.instance_variable_set(:@hours_in_interval, hours_in_month)
expect(cbd.hourly(rate)).to eq(hourly_rate)
expect(cbd.hourly(rate, consumption)).to eq(hourly_rate)
end
cbd = FactoryGirl.build(:chargeback_rate_detail, :per_time => 'annually')
expect { cbd.hourly(rate) }.to raise_error(RuntimeError, "rate time unit of 'annually' not supported")
expect { cbd.hourly(rate, consumption) }.to raise_error(RuntimeError, "rate time unit of 'annually' not supported")
end

it "#rate_adjustment" do
Expand Down Expand Up @@ -195,14 +194,12 @@
:metric => 'derived_memory_available',
:per_time => 'monthly',
:chargeback_rate_detail_measure_id => cbdm.id)
cbd_bytes.instance_variable_set(:@hours_in_interval, hours_in_month)
cbd_gigabytes = FactoryGirl.build(:chargeback_rate_detail,
:per_unit => 'gigabytes',
:metric => 'derived_memory_available',
:per_time => 'monthly',
:chargeback_rate_detail_measure_id => cbdm.id)
cbd_gigabytes.instance_variable_set(:@hours_in_interval, hours_in_month)
expect(cbd_bytes.hourly_cost(100)).to eq(cbd_gigabytes.hourly_cost(100))
expect(cbd_bytes.hourly_cost(100, consumption)).to eq(cbd_gigabytes.hourly_cost(100, consumption))
end

it "#show_rates" do
Expand Down

0 comments on commit 09cecec

Please sign in to comment.