lib/compensate.rb in compensate-0.1.2 vs lib/compensate.rb in compensate-0.1.3
- old
+ new
@@ -1,119 +1,117 @@
-require "compensate/version"
-require "csv"
+require 'compensate/version'
+require 'csv'
module Compensate
class ProjectSet
- RATE_HIGH = '85'
- RATE_LOW = '75'
- TRAVEL_RATE_HIGH = '55'
- TRAVEL_RATE_LOW = '45'
+ RATE_HIGH = '85'.freeze
+ RATE_LOW = '75'.freeze
+ TRAVEL_RATE_HIGH = '55'.freeze
+ TRAVEL_RATE_LOW = '45'.freeze
-
def initialize(csv)
@projects = projects_from_csv(csv)
end
def total
- build_billing_hash
+ parse_projects_and_handle_duplicates
+ apply_billing_rates_to_hash
calculate_total
end
private
- def has_been_logged?(day)
- billing_hash.key?(date_to_string(day))
- end
-
- def hash_entry_for(day)
- billing_hash[date_to_string(day)].to_sym
- end
-
- def build_billing_hash
+ def parse_projects_and_handle_duplicates
# Split projects up and determine what rate to bill at
@projects.each do |project|
rate = project[:rate]
days_in(project).each do |day|
date = date_to_string(day)
- if has_been_logged?(day)
- billing_hash[date] = if billing_hash[date] == 'high'
- 'high'
- else
- billing_hash[date]
- end
- else
- billing_hash[date] = rate
- end
+ billing_hash[date] = rate unless has_been_logged?(day)
end
end
end
- def calculate_total
+ def apply_billing_rates_to_hash
+ # splice in the correct billing rate
billing_hash.each do |k, v|
billing_hash[k] = if v == 'low'
RATE_LOW
else
RATE_HIGH
end
end
+ end
+ def calculate_total
+ total = all_project_sums.map(&:sum)
+ "Total is $#{total.sum}.00"
+ end
+
+ def all_project_sums
+ ranges = split_projects_into_ranges
+
+ # Apply travel rate to first and last days in each range
+ ranges.each do |range|
+ range.each_with_index do |r, i|
+ r[1] = travel_rate_for(r) if (i == 0) || (i == range.size - 1)
+ end
+ end
+
+ # Sum each range's billing amount
+ ranges.map do |range|
+ range.map { |r| total = + r[1].to_i }
+ end
+ end
+
+ def split_projects_into_ranges
date_array = billing_hash.to_a
previous = date_array[0]
+ # Calculate where project ranges have gaps
ranges = date_array.slice_before do |e|
subsequent = previous
previous = e
to_date(subsequent[0]).next_day != to_date(e[0])
end
+ end
- ranges.each do |range|
- range.each_with_index do |r, i|
- if (i == 0) || (i == range.size - 1)
- r[1] = travel_rate(r)
- end
- end
- end
+ def days_in(project)
+ start_date = to_date(project[:start])
+ end_date = to_date(project[:end])
- sums = ranges.map do |range|
- range.map { |r| total =+ r[1].to_i }
- end
+ (start_date..end_date)
+ end
- total = sums.map(&:sum)
- "Total is $#{total.sum}.00"
+ def has_been_logged?(day)
+ billing_hash.key?(date_to_string(day))
end
- def travel_rate(day)
+ def travel_rate_for(day)
case day[1]
when RATE_HIGH
TRAVEL_RATE_HIGH
when RATE_LOW
TRAVEL_RATE_LOW
end
end
- def days_in(project)
- start = to_date(project[:start])
- end_date = to_date(project[:end])
-
- (start..end_date)
- end
-
def to_date(string)
DateTime.strptime(string.to_s, date_format)
end
def date_to_string(date)
date.strftime(date_format)
end
- def date_format
+ def date_format
'%m/%d/%y'
end
def projects_from_csv(csv)
project_array = []
CSV.foreach(csv, headers: true) do |row|
- project_array << {rate: row[0], start: row[1], end: row[2]}
+ project_array << { rate: row[0], start: row[1], end: row[2] }
end
project_array
end
def billing_hash