bamboozled 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,13 +1,11 @@
1
- require 'rake/testtask'
1
+ require "bundler/gem_tasks"
2
2
 
3
- Rake::TestTask.new do |t|
4
- t.test_files = FileList['spec/lib/bamboozled/*_spec.rb']
5
- t.verbose = true
6
- end
7
-
8
- task :default => :test
3
+ require "rspec/core/rake_task"
4
+ RSpec::Core::RakeTask.new(:spec)
9
5
 
10
6
  desc "Open an irb session preloaded with this library"
11
7
  task :console do
12
8
  sh "irb -rubygems -I lib -r bamboozled.rb"
13
9
  end
10
+
11
+ task default: :spec
@@ -1,25 +1,31 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'bamboozled/version'
4
+ require "bamboozled/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "bamboozled"
8
8
  spec.version = Bamboozled::VERSION
9
9
  spec.authors = ["Mark Rickert"]
10
10
  spec.email = ["mjar81@gmail.com"]
11
- spec.summary = "A Ruby Wrapper for the BambooHR API http://www.bamboohr.com/"
11
+ spec.summary = "A Ruby wrapper for the BambooHR API http://www.bamboohr.com/"
12
12
  spec.description = "Bamboozled wraps the BambooHR API without the use of Rails dependencies."
13
13
  spec.homepage = "http://github.com/Skookum/bamboozled"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
- spec.test_files = spec.files.grep(%r{^(spec)/})
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
19
  spec.require_paths = ["lib"]
19
20
 
20
- spec.required_ruby_version = '>= 2.0'
21
+ spec.required_ruby_version = ">= 2.0"
21
22
 
22
- spec.add_runtime_dependency('httparty')
23
- spec.add_runtime_dependency('json')
24
- spec.add_runtime_dependency('activesupport')
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.4"
25
+ spec.add_development_dependency "rspec", "~> 3.1"
26
+ spec.add_development_dependency "webmock", "~> 1.20"
27
+
28
+ spec.add_dependency "httparty", "~> 0.13"
29
+ spec.add_dependency "json", "~> 1.8"
30
+ spec.add_dependency "activesupport"
25
31
  end
@@ -1,14 +1,16 @@
1
- require 'httparty'
2
- require 'json'
3
- require 'uri'
1
+ require "httparty"
2
+ require "json"
3
+ require "uri"
4
4
 
5
- require_relative './bamboozled/ext/yesno'
6
-
7
- require_relative './bamboozled/version'
8
- require_relative './bamboozled/errors'
9
- require_relative './bamboozled/base'
10
-
11
- %w(base employee report time_off meta).each {|a| require_relative "./bamboozled/api/#{a}"}
5
+ require "bamboozled/version"
6
+ require "bamboozled/base"
7
+ require "bamboozled/errors"
8
+ require "bamboozled/ext/yesno"
9
+ require "bamboozled/api/base"
10
+ require "bamboozled/api/employee"
11
+ require "bamboozled/api/report"
12
+ require "bamboozled/api/time_off"
13
+ require "bamboozled/api/meta"
12
14
 
13
15
  module Bamboozled
14
16
  class << self
@@ -1,4 +1,5 @@
1
1
  require 'json'
2
+ require "time"
2
3
  require 'active_support/core_ext/hash/indifferent_access'
3
4
 
4
5
  module Bamboozled
@@ -35,7 +36,11 @@ module Bamboozled
35
36
  case response.code
36
37
  when 200..201
37
38
  begin
38
- JSON.parse(response).with_indifferent_access
39
+ if response.body.to_s.empty?
40
+ {"headers" => response.headers}.with_indifferent_access
41
+ else
42
+ JSON.parse(response.body).with_indifferent_access
43
+ end
39
44
  rescue
40
45
  MultiXml.parse(response, symbolize_keys: true)
41
46
  end
@@ -23,6 +23,15 @@ module Bamboozled
23
23
  request(:get, "employees/#{employee_id}?fields=#{fields}")
24
24
  end
25
25
 
26
+ def last_changed(date = "2011-06-05T00:00:00+00:00", type = nil)
27
+ query = Hash.new
28
+ query[:since] = date.respond_to?(:iso8601) ? date.iso8601 : date
29
+ query[:type] = type unless type.nil?
30
+
31
+ response = request(:get, "employees/changed", query: query)
32
+ response["employees"]
33
+ end
34
+
26
35
  # Tabular data
27
36
  [:job_info, :employment_status, :compensation, :dependents, :contacts].each do |action|
28
37
  define_method(action.to_s) do |argument_id|
@@ -54,6 +63,29 @@ module Bamboozled
54
63
  "http://#{@subdomain}.bamboohr.com/employees/photos/?h=#{digest}"
55
64
  end
56
65
 
66
+ def add(employee_details)
67
+ details = generate_xml(employee_details)
68
+ options = {body: details}
69
+
70
+ request(:post, "employees/", options)
71
+ end
72
+
73
+ def update(bamboo_id, employee_details)
74
+ details = generate_xml(employee_details)
75
+ options = { body: details }
76
+
77
+ request(:post, "employees/#{bamboo_id}", options)
78
+ end
79
+
80
+ private
81
+
82
+ def generate_xml(employee_details)
83
+ "".tap do |xml|
84
+ xml << "<employee>"
85
+ employee_details.each { |k, v| xml << "<field id='#{k}'>#{v}</field>" }
86
+ xml << "</employee>"
87
+ end
88
+ end
57
89
  end
58
90
  end
59
91
  end
@@ -1,9 +1,8 @@
1
1
  module Bamboozled
2
2
  module API
3
3
  class TimeOff < Base
4
-
5
4
  def requests(options = {})
6
- allowed_parameters = [:id, :action, :employeeId, :start, :end, :type, :status]
5
+ allowed_parameters = %i(id action employeeId start end type status)
7
6
  options = options.keep_if { |k,_| allowed_parameters.include? k }
8
7
 
9
8
  # Convert non string dates to strings.
@@ -14,7 +13,9 @@ module Bamboozled
14
13
  # Make sure all statuses are allowed
15
14
  if options[:status]
16
15
  allowed_statuses = %w(approved denied superceded requested canceled)
17
- options[:status] = Array(options[:status]).keep_if { |v| allowed_statuses.include? v }.join(",")
16
+ options[:status] = Array(options[:status])
17
+ .keep_if { |v| allowed_statuses.include? v }
18
+ .join(",")
18
19
  end
19
20
 
20
21
  request(:get, "time_off/requests?#{URI.encode_www_form(options)}")
@@ -12,20 +12,22 @@ module Bamboozled
12
12
  end
13
13
 
14
14
  def to_s
15
- "#{self.class.to_s} : #{response.code} #{response.body}" + (hint ? "\n#{hint}" : "")
15
+ "#{self.class} : #{response.code} #{response.body}".tap do |msg|
16
+ msg << "\n#{hint}" if hint
17
+ end
16
18
  end
17
19
  end
18
20
 
19
- class BadRequest < HTTPError; end #400
20
- class Unauthorized < HTTPError ; end #
21
- class AuthenticationFailed < HTTPError ; end #
22
- class Forbidden < HTTPError ; end # 403
23
- class NotFound < HTTPError; end # 404
24
- class NotAcceptable < HTTPError; end # 406
25
- class Conflict < HTTPError; end # 409
26
- class LimitExceeded < HTTPError; end # 429
27
- class InternalServerError < HTTPError; end # 500
28
- class GatewayError < HTTPError; end # 502
29
- class ServiceUnavailable < HTTPError; end # 503
21
+ class BadRequest < HTTPError; end
22
+ class Unauthorized < HTTPError; end
23
+ class AuthenticationFailed < HTTPError; end
24
+ class Forbidden < HTTPError; end
25
+ class NotFound < HTTPError; end
26
+ class NotAcceptable < HTTPError; end
27
+ class Conflict < HTTPError; end
28
+ class LimitExceeded < HTTPError; end
29
+ class InternalServerError < HTTPError; end
30
+ class GatewayError < HTTPError; end
31
+ class ServiceUnavailable < HTTPError; end
30
32
  class InformBamboo < HTTPError; end
31
33
  end
@@ -1,3 +1,3 @@
1
1
  module Bamboozled
2
- VERSION = "0.0.7"
2
+ VERSION = "0.1.0".freeze
3
3
  end
@@ -0,0 +1,175 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
5
+ viewBox="0 0 808 808" enable-background="new 0 0 808 808" xml:space="preserve">
6
+ <g enable-background="new ">
7
+ <g>
8
+ <defs>
9
+ <rect id="SVGID_1_" x="120" y="163" width="570" height="486"/>
10
+ </defs>
11
+ <clipPath id="SVGID_2_">
12
+ <use xlink:href="#SVGID_1_" overflow="visible"/>
13
+ </clipPath>
14
+ <g clip-path="url(#SVGID_2_)">
15
+ <defs>
16
+ <rect id="SVGID_3_" width="808" height="808"/>
17
+ </defs>
18
+ <clipPath id="SVGID_4_">
19
+ <use xlink:href="#SVGID_3_" overflow="visible"/>
20
+ </clipPath>
21
+ <g clip-path="url(#SVGID_4_)">
22
+ <defs>
23
+ <path id="SVGID_5_" d="M593.3,648.6H423.4c-2.9,0-5.3-2.4-5.3-5.3l-0.1-269.1c0-1.2,1.4-1.3,1.6-0.1l13.7,91.6
24
+ c4.7,31,27.7,70.5,52.2,89.9l109.9,86.6C600.1,645.7,599.1,648.6,593.3,648.6"/>
25
+ </defs>
26
+ <clipPath id="SVGID_6_">
27
+ <use xlink:href="#SVGID_5_" overflow="visible"/>
28
+ </clipPath>
29
+ <g clip-path="url(#SVGID_6_)">
30
+ <defs>
31
+ <rect id="SVGID_7_" width="808" height="808"/>
32
+ </defs>
33
+ <clipPath id="SVGID_8_">
34
+ <use xlink:href="#SVGID_7_" overflow="visible"/>
35
+ </clipPath>
36
+ <rect x="413.1" y="368.2" clip-path="url(#SVGID_8_)" width="190.3" height="285.4"/>
37
+ </g>
38
+ </g>
39
+ </g>
40
+ <g clip-path="url(#SVGID_2_)">
41
+ <defs>
42
+ <rect id="SVGID_9_" width="808" height="808"/>
43
+ </defs>
44
+ <clipPath id="SVGID_10_">
45
+ <use xlink:href="#SVGID_9_" overflow="visible"/>
46
+ </clipPath>
47
+ <g clip-path="url(#SVGID_10_)">
48
+ <defs>
49
+ <path id="SVGID_11_" d="M388.7,374.1l-13.8,91.6c-4.7,31-27.7,70.5-52.2,89.9l-109.9,86.6c-4.6,3.6-3.6,6.5,2.2,6.5h169.9
50
+ c2.9,0,5.3-2.4,5.3-5.3l0.1-269.1C390.2,373,388.8,372.9,388.7,374.1"/>
51
+ </defs>
52
+ <clipPath id="SVGID_12_">
53
+ <use xlink:href="#SVGID_11_" overflow="visible"/>
54
+ </clipPath>
55
+ <g clip-path="url(#SVGID_12_)">
56
+ <defs>
57
+ <rect id="SVGID_13_" width="808" height="808"/>
58
+ </defs>
59
+ <clipPath id="SVGID_14_">
60
+ <use xlink:href="#SVGID_13_" overflow="visible"/>
61
+ </clipPath>
62
+ <rect x="204.9" y="368.2" clip-path="url(#SVGID_14_)" width="190.3" height="285.4"/>
63
+ </g>
64
+ </g>
65
+ </g>
66
+ <g clip-path="url(#SVGID_2_)">
67
+ <defs>
68
+ <rect id="SVGID_15_" width="808" height="808"/>
69
+ </defs>
70
+ <clipPath id="SVGID_16_">
71
+ <use xlink:href="#SVGID_15_" overflow="visible"/>
72
+ </clipPath>
73
+ <g clip-path="url(#SVGID_16_)">
74
+ <defs>
75
+ <path id="SVGID_17_" d="M686.3,484.6L497,167.7c-1.4-2.3-4.6-4.1-7.3-4.1h-170c-2.6,0-5.9,1.9-7.3,4.1l-189,316.8
76
+ c-2.9,4.9-0.9,7.4,4.5,5.7L283.5,440c12.8-4.1,28-18.9,32.6-31.6l63.8-178.1c1-2.7,4.1-5,7-5h34.8c2.9,0,6.1,2.3,7,5
77
+ l63.8,178.1c4.6,12.7,19.8,27.5,32.6,31.6l156.8,50.4C687.2,492,689.2,489.5,686.3,484.6"/>
78
+ </defs>
79
+ <clipPath id="SVGID_18_">
80
+ <use xlink:href="#SVGID_17_" overflow="visible"/>
81
+ </clipPath>
82
+ <g clip-path="url(#SVGID_18_)">
83
+ <defs>
84
+ <rect id="SVGID_19_" width="808" height="808"/>
85
+ </defs>
86
+ <clipPath id="SVGID_20_">
87
+ <use xlink:href="#SVGID_19_" overflow="visible"/>
88
+ </clipPath>
89
+ <rect x="117.2" y="158.6" clip-path="url(#SVGID_20_)" width="575.4" height="337.2"/>
90
+ </g>
91
+ </g>
92
+ </g>
93
+ <g clip-path="url(#SVGID_2_)">
94
+ <defs>
95
+ <rect id="SVGID_21_" width="808" height="808"/>
96
+ </defs>
97
+ <clipPath id="SVGID_22_">
98
+ <use xlink:href="#SVGID_21_" overflow="visible"/>
99
+ </clipPath>
100
+ <g clip-path="url(#SVGID_22_)">
101
+ <defs>
102
+ <path id="SVGID_23_" d="M347.4,461.4l13.6-90.2c0.2-1.3-1.5-2-2-0.5l-16.7,47.2c-7.4,20.7-29.5,42.1-50.2,48.8l-162.5,52.5
103
+ c-3.1,1-4.2,4-2.4,6.8l59.2,94c1.7,2.7,5.2,3.3,7.7,1.3l111.5-87.8C324.5,518.5,343.7,485.5,347.4,461.4"/>
104
+ </defs>
105
+ <clipPath id="SVGID_24_">
106
+ <use xlink:href="#SVGID_23_" overflow="visible"/>
107
+ </clipPath>
108
+ <g clip-path="url(#SVGID_24_)">
109
+ <defs>
110
+ <rect id="SVGID_25_" width="808" height="808"/>
111
+ </defs>
112
+ <clipPath id="SVGID_26_">
113
+ <use xlink:href="#SVGID_25_" overflow="visible"/>
114
+ </clipPath>
115
+ <rect x="121.2" y="364.9" clip-path="url(#SVGID_26_)" width="244.8" height="262.6"/>
116
+ </g>
117
+ </g>
118
+ </g>
119
+ <g clip-path="url(#SVGID_2_)">
120
+ <defs>
121
+ <rect id="SVGID_27_" width="808" height="808"/>
122
+ </defs>
123
+ <clipPath id="SVGID_28_">
124
+ <use xlink:href="#SVGID_27_" overflow="visible"/>
125
+ </clipPath>
126
+ <g clip-path="url(#SVGID_28_)">
127
+ <defs>
128
+ <path id="SVGID_29_" d="M678.9,519.1l-162.5-52.5c-20.8-6.7-42.8-28.2-50.2-48.8l-16.7-47.2c-0.5-1.5-2.2-0.8-2,0.5l13.5,90.2
129
+ c3.7,24,22.8,57.1,41.9,72l111.5,87.8c2.5,2,6,1.4,7.7-1.3l59.3-94C683,523.2,681.9,520.1,678.9,519.1"/>
130
+ </defs>
131
+ <clipPath id="SVGID_30_">
132
+ <use xlink:href="#SVGID_29_" overflow="visible"/>
133
+ </clipPath>
134
+ <g clip-path="url(#SVGID_30_)">
135
+ <defs>
136
+ <rect id="SVGID_31_" width="808" height="808"/>
137
+ </defs>
138
+ <clipPath id="SVGID_32_">
139
+ <use xlink:href="#SVGID_31_" overflow="visible"/>
140
+ </clipPath>
141
+ <rect x="442.4" y="364.9" clip-path="url(#SVGID_32_)" width="244.7" height="262.6"/>
142
+ </g>
143
+ </g>
144
+ </g>
145
+ <g clip-path="url(#SVGID_2_)">
146
+ <defs>
147
+ <rect id="SVGID_33_" width="808" height="808"/>
148
+ </defs>
149
+ <clipPath id="SVGID_34_">
150
+ <use xlink:href="#SVGID_33_" overflow="visible"/>
151
+ </clipPath>
152
+ <g clip-path="url(#SVGID_34_)">
153
+ <defs>
154
+ <path id="SVGID_35_" d="M590.5,246.3c0-9.2,7.3-16.8,16.2-16.8s16.2,7.6,16.2,16.8s-7.3,16.8-16.2,16.8
155
+ S590.5,255.5,590.5,246.3z M586,246.3c0,11.8,9.3,21.3,20.7,21.3c11.5,0,20.7-9.5,20.7-21.3c0-11.8-9.3-21.3-20.7-21.3
156
+ C595.3,225,586,234.5,586,246.3z M610.2,242c0,3.2-2.9,3.4-6.9,3.4v-6.6C608.4,238.8,610.2,239.1,610.2,242z M616.8,258
157
+ l-6.7-9.5c3-1,4.6-3.8,4.6-6.6c0-4.8-2.8-6.8-11.2-6.8h-4.6V258h4.4v-9.3h1.5l6.7,9.3H616.8z"/>
158
+ </defs>
159
+ <clipPath id="SVGID_36_">
160
+ <use xlink:href="#SVGID_35_" overflow="visible"/>
161
+ </clipPath>
162
+ <g clip-path="url(#SVGID_36_)">
163
+ <defs>
164
+ <rect id="SVGID_37_" width="808" height="808"/>
165
+ </defs>
166
+ <clipPath id="SVGID_38_">
167
+ <use xlink:href="#SVGID_37_" overflow="visible"/>
168
+ </clipPath>
169
+ <rect x="581" y="220" clip-path="url(#SVGID_38_)" fill="#393939" width="51.5" height="52.7"/>
170
+ </g>
171
+ </g>
172
+ </g>
173
+ </g>
174
+ </g>
175
+ </svg>
@@ -0,0 +1,13 @@
1
+ ### New Features
2
+
3
+ * New method `Employee#add` allows client to create new employees. ([@kylefdoherty][])
4
+ * New method `Employee#update` allows client to update new employees. ([@kylefdoherty][])
5
+
6
+ ### Changes
7
+
8
+ ### Bug Fixes
9
+
10
+ * Added missing documentation for `Employee#add`. ([@mjording][])
11
+
12
+ [@kylefdoherty]: https://github.com/kylefdoherty
13
+ [@mjording]: https://github.com/mjording
@@ -0,0 +1,7 @@
1
+ {
2
+ "firstName": "Bruce",
3
+ "lastName": "Wayne",
4
+ "workEmail": "bruce.wayne@gmail.com",
5
+ "jobTitle": "Batman",
6
+ "city": "Gotham"
7
+ }
@@ -0,0 +1,4 @@
1
+ HTTP/1.1 200 OK
2
+ content-type: application/json; charset=utf-8
3
+ date: Tue, 17 Jun 2014 19:25:35 UTC
4
+ location: https://api.bamboohr.com/api/gateway.php/alphasights/v1/employees/44259
@@ -0,0 +1,8 @@
1
+ body:
2
+ <employee><field id='firstName'>Bruce</field><field id='lastName'>Wayne</field><field id='workEmail'>bruce.wayne@gmail.com</field><field id='jobTitle'>Batman</field><field id='city'>Gotham</field></employee>
3
+ headers:
4
+ Accept:
5
+ - application/json
6
+ User-Agent:
7
+ - Bamboozled/0.0.7
8
+
@@ -0,0 +1,28 @@
1
+ HTTP/1.1 200 OK
2
+ content-type: application/json; charset=utf-8
3
+ date: Tue, 17 Jun 2014 19:25:35 UTC
4
+
5
+ {
6
+ "employees": {
7
+ "3": {
8
+ "id":"3",
9
+ "action":"Inserted",
10
+ "lastChanged":"2011-06-02T19:26:23+00:00"
11
+ },
12
+ "4": {
13
+ "id":"4",
14
+ "action":"Updated",
15
+ "lastChanged":"2011-06-02T19:26:23+00:00"
16
+ },
17
+ "5": {
18
+ "id":"5",
19
+ "action":"Deleted",
20
+ "lastChanged":"2011-06-02T19:26:23+00:00"
21
+ },
22
+ "10": {
23
+ "id":"10",
24
+ "action":"Inserted",
25
+ "lastChanged":"2011-05-31T22:57:10+00:00"
26
+ }
27
+ }
28
+ }