harvest-ruby-v2 0.3.3 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 657bfe3e49665ad68a2d7498b8b775b6d7704701a807cbce5739d52e677e405b
4
- data.tar.gz: 9ced52a03ca53b10967c20e87ad156259c457d957a134196f89c403b6e97fc01
3
+ metadata.gz: cffdd572f038a6df6e90e8f2380d03c0b035dc687bd7ad49748a5e93c936095c
4
+ data.tar.gz: 60e6607a331fd3d6a892d803f7663050ccd61456bec9b84089d279f9c9b7a9fd
5
5
  SHA512:
6
- metadata.gz: 257341d20fd30a3e582784368020e32a903d9a87e9b6487aa6f6d1e85a57d170ccaf8082b9818da285d93c079bfad65925780e779430039e194fc85ffde426da
7
- data.tar.gz: 40a10bf4c46b6d48db61e4a4a8eeef8afd1db7e5a37c1018279967a1e02b6ace9314e12759d72080ba55fce393f8271a8b5874c83d8724d39de7f97f85a8146d
6
+ metadata.gz: 516bd47d51be828209b10d602c67bf2845a619bbbbacaa51b10ca2aeda4ad639a761455b6e6ff83f87854c06943ab6743eb42878b746e6276d624f90cd96bbe2
7
+ data.tar.gz: d42421df510e3d08e7a9e1ff8d9410911c3897a069e2270cabc966da8cc4c564afffd804b03b331d45791b7fa9e4a2dc1c6bbed4e66c8213447abaa681079244
data/CHANGELOG.rst CHANGED
@@ -0,0 +1,13 @@
1
+ ##########################
2
+ Changelog for harvest-ruby
3
+ ##########################
4
+
5
+ 0.5.1
6
+ ^^^^^
7
+
8
+ * Harvest API external_reference on time entries now contains account_id, updated Struct
9
+
10
+ 0.5.0
11
+ ^^^^^
12
+
13
+ * Fixed bug with ApiCall which caused query params to not be passed to the underlying call.
data/Gemfile CHANGED
@@ -8,6 +8,7 @@ gemspec
8
8
  gem 'activesupport', '~> 6.0'
9
9
  gem 'configparser', '~> 0.1.7', group: :development
10
10
  gem 'pry', '~> 0.13.1', group: :development
11
+ gem 'pry-stack_explorer', '~> 0.5.1', group: :development
11
12
  gem 'rake', '~> 12.0', group: :development
12
13
  gem 'redcarpet', '~> 3.5', group: :development
13
14
  gem 'reek', '~> 6.0', group: :development
data/Rakefile CHANGED
@@ -9,6 +9,8 @@ RSpec::Core::RakeTask.new(:spec)
9
9
  RuboCop::RakeTask.new(:spec) do |rubocop|
10
10
  rubocop.options << '--auto-correct'
11
11
  rubocop.options << '--display-cop-names'
12
+ rubocop.options << '--extra-details'
13
+ rubocop.options << '--display-style-guide'
12
14
  end
13
15
 
14
16
  YARD::Rake::YardocTask.new do |t|
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pry'
4
+ require 'pry-stack_explorer'
5
5
  require 'configparser'
6
6
  require 'date'
7
7
  require "bundler/setup"
data/lib/harvest.rb CHANGED
@@ -11,9 +11,11 @@ require 'harvest/exceptions'
11
11
  require 'harvest/finders'
12
12
  require 'harvest/discovers'
13
13
  require 'harvest/creates'
14
+ require 'harvest/changers'
14
15
 
15
16
  # Conform to naming pattern of Finder, Discover, Creators.
16
17
  # @param key [Symbol] symbol of state
18
+ # @return [Symbol] Symbol to use in class lookups
17
19
  def to_class_name(key)
18
20
  key.to_s.split('_').map(&:capitalize).join.to_sym
19
21
  end
@@ -38,14 +40,17 @@ module Harvest
38
40
  @client = Harvest::HTTP::Api.new(**@config)
39
41
  @factory = Harvest::ResourceFactory.new
40
42
  @state = state
41
- @active_user = @factory.user(@client.api_call(@client.api_caller('/users/me')))
42
- @admin_api = if @active_user.is_admin
43
+ @admin_api = if active_user.is_admin
43
44
  config.admin_api
44
45
  else
45
46
  false
46
47
  end
47
48
  end
48
49
 
50
+ def active_user
51
+ @state[:active_user] ||= @factory.user(@client.api_call(@client.api_caller('/users/me')))
52
+ end
53
+
49
54
  def allowed?(meth)
50
55
  %i[
51
56
  projects
@@ -90,6 +95,16 @@ module Harvest
90
95
  self
91
96
  end
92
97
 
98
+ # Find single instance of resource
99
+ def change(**kwargs)
100
+ @state[@state[:active]].map do |_obj|
101
+ Harvest::Changers.const_get(to_class_name(@state[:active])).new.change(
102
+ @factory, @client, active_user, @state, kwargs
103
+ )
104
+ end
105
+ self
106
+ end
107
+
93
108
  # Discover resources
94
109
  def discover(**params)
95
110
  @state[@state[:active]] = Harvest::Discovers
@@ -101,6 +116,16 @@ module Harvest
101
116
  self
102
117
  end
103
118
 
119
+ # Create an instance of object based on state
120
+ def create(**kwargs)
121
+ @state[@state[:active]] = Harvest::Create.const_get(
122
+ to_class_name(@state[:active])
123
+ ).new.create(
124
+ @factory, @client, active_user, @state, kwargs
125
+ )
126
+ self
127
+ end
128
+
104
129
  # Select a subset of all items depending on state
105
130
  def select(&block)
106
131
  @state[@state[:active]] = @state[@state[:active]].select(&block)
@@ -116,15 +141,5 @@ module Harvest
116
141
  def data
117
142
  @state[@state[:active]]
118
143
  end
119
-
120
- # Create an instance of object based on state
121
- def create(**kwargs)
122
- @state[@state[:active]] = Harvest::Create.const_get(
123
- to_class_name(@state[:active])
124
- ).new.create(
125
- @factory, @client, active_user, @state, kwargs
126
- )
127
- self
128
- end
129
144
  end
130
145
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Harvest
4
+ module Changers
5
+ class TimeEntry
6
+ def change(factory, client, _active_user, state, kwargs)
7
+ # binding.pry
8
+ state[state[:active]].map do |te|
9
+ send(kwargs[:action].to_sym, factory, client, te)
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def restart(factory, client, te)
16
+ # PATCH /v2/time_entries/{TIME_ENTRY_ID}/restart
17
+ # binding.pry
18
+ [factory.time_entry(client.api_call(client.api_caller("time_entries/#{te.id}/restart", http_method: 'patch')))]
19
+ end
20
+
21
+ def stop(factory, client, te)
22
+ # PATCH /v2/time_entries/{TIME_ENTRY_ID}/stop
23
+ [factory.time_entry(client.api_call(client.api_caller("time_entries/#{te.id}/stop", http_method: 'patch')))]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -34,8 +34,8 @@ module Harvest
34
34
 
35
35
  # @api private
36
36
  def time_entry_payload(kwargs)
37
- possible_keys = %i[spent_date notes external_reference user_id]
38
- payload = kwargs.map { |k, v| [k, v] if possible_keys.include?(k) }.to_h
37
+ possible_keys = %i[spent_date notes external_reference user_id project_id task_id]
38
+ payload = kwargs.each { |k, v| [k, v] if possible_keys.include?(k) }.to_h
39
39
  payload[:user_id] ||= @active_user.id
40
40
  payload[:task_id] = @state[:project_tasks][0].task.id
41
41
  payload[:project_id] = true_project(@state[:projects][0]).id
@@ -43,6 +43,9 @@ module Harvest
43
43
  paginator.path = 'time_entries'
44
44
  paginator.data_key = 'time_entries'
45
45
  paginator.param = params
46
+
47
+ # require 'pry'; binding.pry
48
+
46
49
  client.pagination(paginator).map do |time_entry|
47
50
  factory.time_entry(time_entry)
48
51
  end
@@ -10,7 +10,7 @@ module Harvest
10
10
 
11
11
  class TimeEntry
12
12
  def find(factory, client, id)
13
- [factory.time_entry(client.api_call(client.api_caller("time_entry/#{id}")))]
13
+ [factory.time_entry(client.api_call(client.api_caller("time_entries/#{id}")))]
14
14
  end
15
15
  end
16
16
  end
@@ -71,7 +71,7 @@ module Harvest
71
71
 
72
72
  # Make a api call to an endpoint.
73
73
  # @api public
74
- # @param struct [Struct::ApiCall]
74
+ # @param struct [ApiCall]
75
75
  def api_call(struct)
76
76
  JSON.parse(
77
77
  send(struct.http_method.to_sym, struct).tap do
@@ -85,7 +85,9 @@ module Harvest
85
85
  # @param struct [Struct::Pagination]
86
86
  def pagination(struct)
87
87
  struct.param[:page] = struct.page_count
88
- page = api_call(struct.to_api_call)
88
+ page = api_call(struct.to_api_call).tap do
89
+ # require 'pry'; binding.pry
90
+ end
89
91
  struct.rows.concat(page[struct.data_key])
90
92
 
91
93
  return struct.rows if struct.page_count >= page['total_pages']
@@ -108,11 +110,11 @@ module Harvest
108
110
  end
109
111
 
110
112
  def api_caller(path, http_method: 'get', param: {}, payload: nil, headers: {})
111
- Struct::ApiCall.new(
113
+ ApiCall.new(
112
114
  {
113
115
  path: path,
114
116
  http_method: http_method.to_sym,
115
- param: param,
117
+ params: param,
116
118
  payload: payload,
117
119
  headers: headers
118
120
  }
@@ -125,22 +127,43 @@ module Harvest
125
127
  client[struct.path].get(struct.headers)
126
128
  end
127
129
 
130
+ def delete(struct)
131
+ client[struct.path].delete(struct.headers)
132
+ end
133
+
128
134
  def post(struct)
129
135
  client[struct.path].post(struct.payload, struct.headers)
130
136
  end
137
+
138
+ def patch(struct)
139
+ client[struct.path].patch(struct.payload, struct.headers)
140
+ end
131
141
  end
132
142
 
133
- Struct.new(
134
- 'ApiCall',
135
- :path,
136
- :http_method,
137
- :param,
138
- :payload,
139
- :headers,
140
- keyword_init: true
141
- ) do
142
- def param(params)
143
- headers['params'] = params
143
+ class NoOptionProvided; end
144
+
145
+ class ApiCall
146
+ attr_accessor :path, :http_method, :payload, :headers
147
+
148
+ def initialize(path:, payload: {}, http_method: 'get', headers: {}, params: {})
149
+ @path = path
150
+ @http_method = http_method
151
+ @payload = payload
152
+ @headers = headers
153
+ param(params)
154
+ end
155
+
156
+ def param(params = NoOptionProvided)
157
+ if params == NoOptionProvided
158
+ @headers['params']
159
+ else
160
+ @headers['params'] = params
161
+ end
162
+ end
163
+
164
+ def param=(params)
165
+ param(params)
166
+ self
144
167
  end
145
168
  end
146
169
 
@@ -157,11 +180,11 @@ module Harvest
157
180
  keyword_init: true
158
181
  ) do
159
182
  def to_api_call
160
- Struct::ApiCall.new(
161
- {
183
+ ApiCall.new(
184
+ **{
162
185
  path: path,
163
186
  http_method: http_method,
164
- param: param,
187
+ params: param,
165
188
  payload: payload,
166
189
  headers: headers
167
190
  }
@@ -26,6 +26,8 @@ module Harvest
26
26
  # associated invoice's id and number.
27
27
  # @param hours [decimal]
28
28
  # Number of (decimal time) hours tracked in this time entry.
29
+ # @param hours_without_timer [decimal]
30
+ # Number of (decimal time) hours already tracked in this time entry, before the timer was last started.
29
31
  # @param rounded_hours [decimal]
30
32
  # Number of (decimal time) hours tracked in this time entry used in summary
31
33
  # reports and invoices. This value is rounded according to the Time Rounding
@@ -73,6 +75,7 @@ module Harvest
73
75
  :external_reference,
74
76
  :invoice,
75
77
  :hours,
78
+ :hours_without_timer,
76
79
  :rounded_hours,
77
80
  :notes,
78
81
  :is_locked,
@@ -95,6 +98,7 @@ module Harvest
95
98
  TimeEntryExternalReference = Struct.new(
96
99
  'TimeEntryExternalReference',
97
100
  :id,
101
+ :account_id,
98
102
  :group_id,
99
103
  :permalink,
100
104
  :service,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Harvest
4
- VERSION = '0.3.3'
4
+ VERSION = '0.5.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: harvest-ruby-v2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Craig Davis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-22 00:00:00.000000000 Z
11
+ date: 2021-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -61,6 +61,7 @@ files:
61
61
  - bin/setup
62
62
  - harvest-ruby-v2.gemspec
63
63
  - lib/harvest.rb
64
+ - lib/harvest/changers.rb
64
65
  - lib/harvest/client.rb
65
66
  - lib/harvest/config.rb
66
67
  - lib/harvest/creates.rb