require 'compensate/version' require 'csv' module Compensate class ProjectSet 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 parse_projects_and_handle_duplicates apply_billing_rates_to_hash calculate_total end private 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) billing_hash[date] = rate unless has_been_logged?(day) end end end 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 def days_in(project) start_date = to_date(project[:start]) end_date = to_date(project[:end]) (start_date..end_date) end def has_been_logged?(day) billing_hash.key?(date_to_string(day)) end def travel_rate_for(day) case day[1] when RATE_HIGH TRAVEL_RATE_HIGH when RATE_LOW TRAVEL_RATE_LOW end 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 '%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] } end project_array end def billing_hash @billing_hash ||= {} end end end