Skip to content

Commit

Permalink
Merge pull request #12616 from isimluk/only-rate-should-know-what-to-…
Browse files Browse the repository at this point in the history
…charge

ChargebackRateDetail should take care of charging
  • Loading branch information
gtanzillo authored Nov 18, 2016
2 parents 2037d28 + 4588c62 commit f0322a3
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 37 deletions.
40 changes: 9 additions & 31 deletions app/models/chargeback.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,42 +141,14 @@ def calculate_costs(metric_rollup_records, rates, hours_in_interval)

rates.each do |rate|
rate.chargeback_rate_details.each do |r|
if !chargeback_fields_present && r.fixed?
cost = 0
else
r.hours_in_interval = hours_in_interval
metric_value = r.metric_value_by(metric_rollup_records)
cost = r.cost(metric_value) * hours_in_interval
r.charge(relevant_fields, chargeback_fields_present, metric_rollup_records, hours_in_interval).each do |field, value|
next unless self.class.attribute_names.include?(field)
self[field] = (self[field] || 0) + value
end

accumulate_metrics_and_costs_per_rate(r.rate_name, r.group, metric_value, cost)
end
end
end

def accumulate_metrics_and_costs_per_rate(rate_name, rate_group, metric, cost)
cost_key = "#{rate_name}_cost" # metric cost value (e.g. Storage [Used|Allocated|Fixed] Cost)
metric_key = "#{rate_name}_metric" # metric value (e.g. Storage [Used|Allocated|Fixed])
cost_group_key = "#{rate_group}_cost" # for total of metric's costs (e.g. Storage Total Cost)
metric_group_key = "#{rate_group}_metric" # for total of metrics (e.g. Storage Total)

col_hash = {}

defined_column_for_report = (self.class.report_col_options.keys & [metric_key, cost_key]).present?

if defined_column_for_report
[metric_key, metric_group_key].each { |col| col_hash[col] = metric }
[cost_key, cost_group_key, 'total_cost'].each { |col| col_hash[col] = cost }
end

col_hash.each do |k, val|
next unless self.class.attribute_names.include?(k)
self[k] ||= 0
self[k] += val
end
end
private :accumulate_metrics_and_costs_per_rate

def self.report_cb_model(model)
model.gsub(/^Chargeback/, "")
end
Expand Down Expand Up @@ -236,4 +208,10 @@ def self.load_custom_attribute(custom_attribute)
entity.send(custom_attribute)
end
end

private

def relevant_fields
@relevant_fields ||= self.class.report_col_options.keys.to_set
end
end # class Chargeback
35 changes: 34 additions & 1 deletion app/models/chargeback_rate_detail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ class ChargebackRateDetail < ApplicationRecord

attr_accessor :hours_in_interval

def charge(relevant_fields, chargeback_fields_present, metric_rollup_records, hours_in_interval)
result = {}
if (relevant_fields & [metric_keys[0], cost_keys[0]]).present?
if !chargeback_fields_present && fixed?
cost = 0
else
metric_value, cost = metric_and_cost_by(metric_rollup_records, hours_in_interval)
end
metric_keys.each { |field| result[field] = metric_value }
cost_keys.each { |field| result[field] = cost }
end
result
end

def max_of_metric_from(metric_rollup_records)
metric_rollup_records.map(&metric.to_sym).max
end
Expand Down Expand Up @@ -74,7 +88,7 @@ def find_rate(value)
:yearly => "Year"
}

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

value = 1.0 if fixed?
Expand Down Expand Up @@ -210,6 +224,25 @@ def contiguous_tiers?
!error
end

private

def metric_keys
["#{rate_name}_metric", # metric value (e.g. Storage [Used|Allocated|Fixed])
"#{group}_metric"] # total of metric's group (e.g. Storage Total)
end

def cost_keys
["#{rate_name}_cost", # cost associated with metric (e.g. Storage [Used|Allocated|Fixed] Cost)
"#{group}_cost", # cost associated with metric's group (e.g. Storage Total Cost)
'total_cost']
end

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

def first_tier?(tier,tiers)
tier == tiers.first
end
Expand Down
10 changes: 5 additions & 5 deletions spec/models/chargeback_rate_detail_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

let(:hours_in_month) { 720 }

it "#cost" do
it '#hourly_cost' do
cvalue = 42.0
fixed_rate = 5.0
variable_rate = 8.26
Expand All @@ -46,13 +46,13 @@
:fixed_rate => fixed_rate,
:variable_rate => variable_rate)
cbd.update(:chargeback_tiers => [cbt])
expect(cbd.cost(cvalue)).to eq(cvalue * cbd.hourly(variable_rate) + cbd.hourly(fixed_rate))
expect(cbd.hourly_cost(cvalue)).to eq(cvalue * cbd.hourly(variable_rate) + cbd.hourly(fixed_rate))

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

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

it "#hourly" do
Expand Down Expand Up @@ -195,7 +195,7 @@
:per_time => 'monthly',
:chargeback_rate_detail_measure_id => cbdm.id,
:hours_in_interval => hours_in_month)
expect(cbd_bytes.cost(100)).to eq(cbd_gigabytes.cost(100))
expect(cbd_bytes.hourly_cost(100)).to eq(cbd_gigabytes.hourly_cost(100))
end

it "#show_rates" do
Expand Down

0 comments on commit f0322a3

Please sign in to comment.