compensate 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c411851f74bb6205ee7d30bd6aee6c58e717e9d
4
- data.tar.gz: 71b4a38d37f1a5899fd10c9a624d8ea8f87a9c41
3
+ metadata.gz: 949fc8bf33efa35797a6375ceaf9e43cec2e9b0d
4
+ data.tar.gz: 577722fd3834171ed51631da7f71b71dd23521ee
5
5
  SHA512:
6
- metadata.gz: 759c60c4802829ee9e3afc9c6fcb7feeecb44e3c6b0ac57d82ae42b37ddb4f3ec6e995699da05a4ba258f0ac96c263a0f7e0734d981e3724399c4329f3e2d7d0
7
- data.tar.gz: 93896f66aea9da7fbce60dc5d42553ecc72e63bd8b7e0028721b85b47bba34dee256086d25c335f67b5cfdc25206d12c722b068980ce9306b0a64735a748fbe8
6
+ metadata.gz: 7b42aa22b8bcb64d910008e6a4770f99923894e1b2e99237f3cf246679979594033d955db657cb1a9a0c8b448a11f2973db639783412cea1b15f31413d43c8b1
7
+ data.tar.gz: f6ce6c77b05f9e8c8d7df66518b55f4bc8ff3a986f0bde84d4dc64f4d800231305e6cd9192a61103899935d79cc6bdeca48e6b798c483d1ccfbcb88fff754e00
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in compensate.gemspec
6
6
  gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- compensate (0.1.0)
4
+ compensate (0.1.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -6,17 +6,7 @@ Completed as a technical exercise during interview process for [Simple Thread](h
6
6
 
7
7
  ## Installation
8
8
 
9
- Add this line to your application's Gemfile:
10
-
11
- ```ruby
12
- gem 'compensate'
13
- ```
14
-
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
9
+ Install this gem directly with:
20
10
 
21
11
  $ gem install compensate
22
12
 
@@ -24,7 +14,7 @@ Or install it yourself as:
24
14
 
25
15
  Inputs accepted are .csv files with the following headers: `Rate, Start, End` where `Rate` is either `high` or `low`, and `Start, End` are dates in the format of `MM/DD/YY`. Ensure the header rows exist on a given CSV.
26
16
 
27
- This gem is packaged with an executable script. Use the following command to process a CSV named `test.csv`:
17
+ This gem is packaged with an executable command-line script. Use the following shell command to process a CSV named `test.csv`:
28
18
 
29
19
  `compensate test.csv`
30
20
 
@@ -36,7 +26,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
36
26
 
37
27
  ## Contributing
38
28
 
39
- Bug reports and pull requests are welcome on GitHub at https://github.com/kfrz/compensate. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
29
+ Bug reports and pull requests are welcome on GitLab at https://gitlab.com/kfrz/compensate. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
40
30
 
41
31
  ## License
42
32
 
@@ -44,4 +34,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
44
34
 
45
35
  ## Code of Conduct
46
36
 
47
- Everyone interacting in the Compensate project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/kfrz/compensate/blob/master/CODE_OF_CONDUCT.md).
37
+ Everyone interacting in the Compensate project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/kfrz/compensate/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "compensate"
3
+ require 'bundler/setup'
4
+ require 'compensate'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "compensate"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start(__FILE__)
data/compensate.gemspec CHANGED
@@ -1,27 +1,27 @@
1
1
 
2
- lib = File.expand_path("../lib", __FILE__)
2
+ lib = File.expand_path('lib', __dir__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "compensate/version"
4
+ require 'compensate/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "compensate"
7
+ spec.name = 'compensate'
8
8
  spec.version = Compensate::VERSION
9
- spec.authors = ["Keifer Furzland"]
10
- spec.email = ["kfrz.code@gmail.com"]
9
+ spec.authors = ['Keifer Furzland']
10
+ spec.email = ['kfrz.code@gmail.com']
11
11
 
12
- spec.summary = "Calculate total reimbursement amount for a given CSV of project date ranges"
13
- spec.homepage = "https://gitlab.com/kfrz/compensate"
14
- spec.license = "MIT"
12
+ spec.summary = 'Calculate total reimbursement amount for a given CSV of project date ranges'
13
+ spec.homepage = 'https://gitlab.com/kfrz/compensate'
14
+ spec.license = 'MIT'
15
15
 
16
16
  # Specify which files should be added to the gem when it is released.
17
17
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
19
19
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
20
  end
21
21
  spec.executables << 'compensate'
22
- spec.require_paths = ["lib"]
22
+ spec.require_paths = ['lib']
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.16"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "rspec", "~> 3.0"
24
+ spec.add_development_dependency 'bundler', '~> 1.16'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec', '~> 3.0'
27
27
  end
@@ -1,3 +1,3 @@
1
1
  module Compensate
2
- VERSION = "0.1.2"
2
+ VERSION = '0.1.3'.freeze
3
3
  end
data/lib/compensate.rb CHANGED
@@ -1,53 +1,38 @@
1
- require "compensate/version"
2
- require "csv"
1
+ require 'compensate/version'
2
+ require 'csv'
3
3
 
4
4
  module Compensate
5
5
  class ProjectSet
6
- RATE_HIGH = '85'
7
- RATE_LOW = '75'
8
- TRAVEL_RATE_HIGH = '55'
9
- TRAVEL_RATE_LOW = '45'
10
-
6
+ RATE_HIGH = '85'.freeze
7
+ RATE_LOW = '75'.freeze
8
+ TRAVEL_RATE_HIGH = '55'.freeze
9
+ TRAVEL_RATE_LOW = '45'.freeze
11
10
 
12
11
  def initialize(csv)
13
12
  @projects = projects_from_csv(csv)
14
13
  end
15
14
 
16
15
  def total
17
- build_billing_hash
16
+ parse_projects_and_handle_duplicates
17
+ apply_billing_rates_to_hash
18
18
  calculate_total
19
19
  end
20
20
 
21
21
  private
22
22
 
23
- def has_been_logged?(day)
24
- billing_hash.key?(date_to_string(day))
25
- end
26
-
27
- def hash_entry_for(day)
28
- billing_hash[date_to_string(day)].to_sym
29
- end
30
-
31
- def build_billing_hash
23
+ def parse_projects_and_handle_duplicates
32
24
  # Split projects up and determine what rate to bill at
33
25
  @projects.each do |project|
34
26
  rate = project[:rate]
35
27
  days_in(project).each do |day|
36
28
  date = date_to_string(day)
37
- if has_been_logged?(day)
38
- billing_hash[date] = if billing_hash[date] == 'high'
39
- 'high'
40
- else
41
- billing_hash[date]
42
- end
43
- else
44
- billing_hash[date] = rate
45
- end
29
+ billing_hash[date] = rate unless has_been_logged?(day)
46
30
  end
47
31
  end
48
32
  end
49
33
 
50
- def calculate_total
34
+ def apply_billing_rates_to_hash
35
+ # splice in the correct billing rate
51
36
  billing_hash.each do |k, v|
52
37
  billing_hash[k] = if v == 'low'
53
38
  RATE_LOW
@@ -55,33 +40,53 @@ module Compensate
55
40
  RATE_HIGH
56
41
  end
57
42
  end
43
+ end
44
+
45
+ def calculate_total
46
+ total = all_project_sums.map(&:sum)
47
+ "Total is $#{total.sum}.00"
48
+ end
49
+
50
+ def all_project_sums
51
+ ranges = split_projects_into_ranges
52
+
53
+ # Apply travel rate to first and last days in each range
54
+ ranges.each do |range|
55
+ range.each_with_index do |r, i|
56
+ r[1] = travel_rate_for(r) if (i == 0) || (i == range.size - 1)
57
+ end
58
+ end
58
59
 
60
+ # Sum each range's billing amount
61
+ ranges.map do |range|
62
+ range.map { |r| total = + r[1].to_i }
63
+ end
64
+ end
65
+
66
+ def split_projects_into_ranges
59
67
  date_array = billing_hash.to_a
60
68
  previous = date_array[0]
61
69
 
70
+ # Calculate where project ranges have gaps
62
71
  ranges = date_array.slice_before do |e|
63
72
  subsequent = previous
64
73
  previous = e
65
74
  to_date(subsequent[0]).next_day != to_date(e[0])
66
75
  end
76
+ end
67
77
 
68
- ranges.each do |range|
69
- range.each_with_index do |r, i|
70
- if (i == 0) || (i == range.size - 1)
71
- r[1] = travel_rate(r)
72
- end
73
- end
74
- end
78
+ def days_in(project)
79
+ start_date = to_date(project[:start])
80
+ end_date = to_date(project[:end])
75
81
 
76
- sums = ranges.map do |range|
77
- range.map { |r| total =+ r[1].to_i }
78
- end
82
+ (start_date..end_date)
83
+ end
79
84
 
80
- total = sums.map(&:sum)
81
- "Total is $#{total.sum}.00"
85
+ def has_been_logged?(day)
86
+ billing_hash.key?(date_to_string(day))
82
87
  end
83
88
 
84
- def travel_rate(day)
89
+ def travel_rate_for(day)
85
90
  case day[1]
86
91
  when RATE_HIGH
87
92
  TRAVEL_RATE_HIGH
@@ -90,13 +95,6 @@ module Compensate
90
95
  end
91
96
  end
92
97
 
93
- def days_in(project)
94
- start = to_date(project[:start])
95
- end_date = to_date(project[:end])
96
-
97
- (start..end_date)
98
- end
99
-
100
98
  def to_date(string)
101
99
  DateTime.strptime(string.to_s, date_format)
102
100
  end
@@ -105,14 +103,14 @@ module Compensate
105
103
  date.strftime(date_format)
106
104
  end
107
105
 
108
- def date_format
106
+ def date_format
109
107
  '%m/%d/%y'
110
108
  end
111
109
 
112
110
  def projects_from_csv(csv)
113
111
  project_array = []
114
112
  CSV.foreach(csv, headers: true) do |row|
115
- project_array << {rate: row[0], start: row[1], end: row[2]}
113
+ project_array << { rate: row[0], start: row[1], end: row[2] }
116
114
  end
117
115
  project_array
118
116
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compensate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keifer Furzland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-04 00:00:00.000000000 Z
11
+ date: 2018-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler