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