harvested 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +33 -0
- data/.ruby-version +1 -1
- data/Gemfile +5 -5
- data/HISTORY +2 -0
- data/Rakefile +2 -22
- data/harvested.gemspec +20 -159
- data/lib/harvest/api/reports.rb +12 -11
- data/lib/harvest/base.rb +2 -3
- data/lib/harvest/behavior/crud.rb +5 -1
- data/lib/harvest/credentials.rb +9 -9
- data/lib/harvest/version.rb +3 -0
- data/lib/harvested.rb +3 -4
- data/spec/functional/invoice_spec.rb +6 -6
- data/spec/functional/reporting_spec.rb +3 -4
- data/spec/spec_helper.rb +6 -2
- data/spec/support/harvested_helpers.rb +2 -7
- metadata +55 -153
- data/VERSION +0 -1
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MDliY2MxNTEwMjFhZmE4NGZhMDJmYzhlNTBjM2JhYzU0MTAxMzAwZA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d2bbcab0b8d5c473899f541789533afac807bc1d
|
4
|
+
data.tar.gz: 2271ae74a87f8108722d0019afb636661728fbad
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZmVkNWRiMGU5YjI5NmJkZDZiMjk3Yjk1MjFhZmI3ZTVkZTQ0ZTFlZWNjNmVm
|
11
|
-
MGUyZTU5OGNjMGU2MmFiMzBjNTg4NWVmNDA4YjQ4ZGNiMWIyYTA=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MjU1NmUxMTY0M2I4OTgxOThlMzEwMDJkODdlMDQ2NmNhMDBhMWU5Njg4MjEw
|
14
|
-
YTg4MjFhZGE3OGYyNDE2NGViZTczNTZjMzA3N2ExZWU1MDQ4NWY0OWViOTFh
|
15
|
-
NDk4MDQ3NTRkNWQxZDU1M2JlNmZlZDQ3Yjg2NmE3NGExNmZhYjE=
|
6
|
+
metadata.gz: edfa9ad33c17a0f759b725788a1c0fe4412609097e6c06a4b16cd553fd49c8429cdc495e23f0313197f555c298eb024fd0f157fbb395aa7c06bd839bf3d4cf61
|
7
|
+
data.tar.gz: 7d37d6f6f261c930e1030ddee9c82557823fcb9795303081f48ecbcd743413709a40841edaf15736b39c0842ba2a1a48fcf3a4cc504b2ab726efff1604a52451
|
data/.gitignore
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## PROJECT::GENERAL
|
17
|
+
coverage
|
18
|
+
rdoc
|
19
|
+
pkg
|
20
|
+
doc
|
21
|
+
.yardoc
|
22
|
+
|
23
|
+
## PROJECT::SPECIFIC
|
24
|
+
features/support/harvest_credentials.yml
|
25
|
+
spec/support/harvest_credentials.yml
|
26
|
+
.cassettes
|
27
|
+
.rbx
|
28
|
+
|
29
|
+
## RUBYGEMS
|
30
|
+
*.gem
|
31
|
+
Gemfile.lock
|
32
|
+
.bundle
|
33
|
+
vendor/bundle
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
2.1.1
|
data/Gemfile
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
gem 'hashie', '~> 1'
|
5
|
-
gem 'json'
|
3
|
+
gemspec
|
6
4
|
|
7
5
|
group :development, :test do
|
6
|
+
gem 'bundler', '>= 1.6.2'
|
7
|
+
gem 'rake'
|
8
|
+
|
8
9
|
gem 'rspec', '~> 2'
|
9
10
|
gem 'jruby-openssl', :platform => [:jruby], :require => false
|
10
11
|
gem 'webmock'
|
11
12
|
gem 'vcr'
|
12
|
-
gem '
|
13
|
-
gem 'debugger'
|
13
|
+
gem 'byebug'
|
14
14
|
gem 'factory_girl'
|
15
15
|
gem 'yard'
|
16
16
|
gem 'redcarpet'
|
data/HISTORY
CHANGED
data/Rakefile
CHANGED
@@ -1,24 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'rake'
|
5
|
-
require "bundler/setup"
|
6
|
-
|
7
|
-
begin
|
8
|
-
require 'jeweler'
|
9
|
-
Jeweler::Tasks.new do |gem|
|
10
|
-
gem.name = "harvested"
|
11
|
-
gem.summary = %Q{A Ruby Wrapper for the Harvest API http://www.getharvest.com/}
|
12
|
-
gem.description = %Q{Harvested wraps the Harvest API concisely without the use of Rails dependencies. More information about the Harvest API can be found on their website (http://www.getharvest.com/api). For support hit up the Mailing List (http://groups.google.com/group/harvested)}
|
13
|
-
gem.email = "zach.moazeni@gmail.com"
|
14
|
-
gem.homepage = "http://github.com/zmoazeni/harvested"
|
15
|
-
gem.authors = ["Zach Moazeni"]
|
16
|
-
end
|
17
|
-
Jeweler::GemcutterTasks.new
|
18
|
-
rescue LoadError => e
|
19
|
-
p e
|
20
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
-
end
|
1
|
+
require 'bundler/gem_tasks'
|
22
2
|
|
23
3
|
require 'rspec/core/rake_task'
|
24
4
|
RSpec::Core::RakeTask.new(:spec)
|
@@ -37,6 +17,6 @@ end
|
|
37
17
|
desc 'Removes all data on harvest'
|
38
18
|
task 'clean_remote' do
|
39
19
|
require 'harvested'
|
40
|
-
require
|
20
|
+
require File.expand_path('../spec/support/harvested_helpers', __FILE__)
|
41
21
|
HarvestedHelpers.clean_remote
|
42
22
|
end
|
data/harvested.gemspec
CHANGED
@@ -1,163 +1,24 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
# stub: harvested 1.2.0 ruby lib
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'harvest/version'
|
6
5
|
|
7
|
-
Gem::Specification.new do |
|
8
|
-
|
9
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "harvested"
|
8
|
+
spec.version = Harvest::VERSION
|
9
|
+
spec.authors = ["Zach Moazeni"]
|
10
|
+
spec.email = ["zach.moazeni@gmail.com"]
|
11
|
+
spec.summary = "A Ruby Wrapper for the Harvest API http://www.getharvest.com/"
|
12
|
+
spec.description = "Harvested wraps the Harvest API concisely without the use of Rails dependencies. More information about the Harvest API can be found on their website (http://www.getharvest.com/api). For support hit up the Mailing List (http://groups.google.com/group/harvested)"
|
13
|
+
spec.homepage = "http://github.com/zmoazeni/harvested"
|
14
|
+
spec.license = "MIT"
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
s.description = "Harvested wraps the Harvest API concisely without the use of Rails dependencies. More information about the Harvest API can be found on their website (http://www.getharvest.com/api). For support hit up the Mailing List (http://groups.google.com/group/harvested)"
|
16
|
-
s.email = "zach.moazeni@gmail.com"
|
17
|
-
s.extra_rdoc_files = [
|
18
|
-
"README.md",
|
19
|
-
"TODO"
|
20
|
-
]
|
21
|
-
s.files = [
|
22
|
-
".document",
|
23
|
-
".ruby-version",
|
24
|
-
"Gemfile",
|
25
|
-
"HISTORY",
|
26
|
-
"MIT-LICENSE",
|
27
|
-
"README.md",
|
28
|
-
"Rakefile",
|
29
|
-
"TODO",
|
30
|
-
"VERSION",
|
31
|
-
"examples/basics.rb",
|
32
|
-
"examples/clear_account.rb",
|
33
|
-
"examples/project_create_script.rb",
|
34
|
-
"examples/task_assignments.rb",
|
35
|
-
"examples/user_assignments.rb",
|
36
|
-
"harvested.gemspec",
|
37
|
-
"lib/ext/array.rb",
|
38
|
-
"lib/ext/date.rb",
|
39
|
-
"lib/ext/hash.rb",
|
40
|
-
"lib/ext/time.rb",
|
41
|
-
"lib/harvest/api/account.rb",
|
42
|
-
"lib/harvest/api/base.rb",
|
43
|
-
"lib/harvest/api/clients.rb",
|
44
|
-
"lib/harvest/api/contacts.rb",
|
45
|
-
"lib/harvest/api/expense_categories.rb",
|
46
|
-
"lib/harvest/api/expenses.rb",
|
47
|
-
"lib/harvest/api/invoice_categories.rb",
|
48
|
-
"lib/harvest/api/invoice_payments.rb",
|
49
|
-
"lib/harvest/api/invoices.rb",
|
50
|
-
"lib/harvest/api/projects.rb",
|
51
|
-
"lib/harvest/api/reports.rb",
|
52
|
-
"lib/harvest/api/task_assignments.rb",
|
53
|
-
"lib/harvest/api/tasks.rb",
|
54
|
-
"lib/harvest/api/time.rb",
|
55
|
-
"lib/harvest/api/user_assignments.rb",
|
56
|
-
"lib/harvest/api/users.rb",
|
57
|
-
"lib/harvest/base.rb",
|
58
|
-
"lib/harvest/behavior/activatable.rb",
|
59
|
-
"lib/harvest/behavior/crud.rb",
|
60
|
-
"lib/harvest/client.rb",
|
61
|
-
"lib/harvest/contact.rb",
|
62
|
-
"lib/harvest/credentials.rb",
|
63
|
-
"lib/harvest/errors.rb",
|
64
|
-
"lib/harvest/expense.rb",
|
65
|
-
"lib/harvest/expense_category.rb",
|
66
|
-
"lib/harvest/hardy_client.rb",
|
67
|
-
"lib/harvest/invoice.rb",
|
68
|
-
"lib/harvest/invoice_category.rb",
|
69
|
-
"lib/harvest/invoice_payment.rb",
|
70
|
-
"lib/harvest/line_item.rb",
|
71
|
-
"lib/harvest/model.rb",
|
72
|
-
"lib/harvest/project.rb",
|
73
|
-
"lib/harvest/rate_limit_status.rb",
|
74
|
-
"lib/harvest/task.rb",
|
75
|
-
"lib/harvest/task_assignment.rb",
|
76
|
-
"lib/harvest/time_entry.rb",
|
77
|
-
"lib/harvest/timezones.rb",
|
78
|
-
"lib/harvest/trackable_project.rb",
|
79
|
-
"lib/harvest/user.rb",
|
80
|
-
"lib/harvest/user_assignment.rb",
|
81
|
-
"lib/harvested.rb",
|
82
|
-
"spec/factories.rb",
|
83
|
-
"spec/functional/account_spec.rb",
|
84
|
-
"spec/functional/clients_spec.rb",
|
85
|
-
"spec/functional/errors_spec.rb",
|
86
|
-
"spec/functional/expenses_spec.rb",
|
87
|
-
"spec/functional/hardy_client_spec.rb",
|
88
|
-
"spec/functional/invoice_payments_spec.rb",
|
89
|
-
"spec/functional/invoice_spec.rb",
|
90
|
-
"spec/functional/project_spec.rb",
|
91
|
-
"spec/functional/reporting_spec.rb",
|
92
|
-
"spec/functional/tasks_spec.rb",
|
93
|
-
"spec/functional/time_tracking_spec.rb",
|
94
|
-
"spec/functional/users_spec.rb",
|
95
|
-
"spec/harvest/base_spec.rb",
|
96
|
-
"spec/harvest/credentials_spec.rb",
|
97
|
-
"spec/harvest/expense_category_spec.rb",
|
98
|
-
"spec/harvest/expense_spec.rb",
|
99
|
-
"spec/harvest/invoice_payment_spec.rb",
|
100
|
-
"spec/harvest/invoice_spec.rb",
|
101
|
-
"spec/harvest/project_spec.rb",
|
102
|
-
"spec/harvest/task_assignment_spec.rb",
|
103
|
-
"spec/harvest/task_spec.rb",
|
104
|
-
"spec/harvest/time_entry_spec.rb",
|
105
|
-
"spec/harvest/trackable_project_spec.rb",
|
106
|
-
"spec/harvest/user_assignment_spec.rb",
|
107
|
-
"spec/harvest/user_spec.rb",
|
108
|
-
"spec/spec_helper.rb",
|
109
|
-
"spec/support/harvest_credentials.example.yml",
|
110
|
-
"spec/support/harvested_helpers.rb",
|
111
|
-
"spec/support/json_examples.rb",
|
112
|
-
"spec/test_rubies"
|
113
|
-
]
|
114
|
-
s.homepage = "http://github.com/zmoazeni/harvested"
|
115
|
-
s.rubygems_version = "2.2.1"
|
116
|
-
s.summary = "A Ruby Wrapper for the Harvest API http://www.getharvest.com/"
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
117
20
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
122
|
-
s.add_runtime_dependency(%q<httparty>, [">= 0"])
|
123
|
-
s.add_runtime_dependency(%q<hashie>, ["~> 1"])
|
124
|
-
s.add_runtime_dependency(%q<json>, [">= 0"])
|
125
|
-
s.add_development_dependency(%q<rspec>, ["~> 2"])
|
126
|
-
s.add_development_dependency(%q<jruby-openssl>, [">= 0"])
|
127
|
-
s.add_development_dependency(%q<webmock>, [">= 0"])
|
128
|
-
s.add_development_dependency(%q<vcr>, [">= 0"])
|
129
|
-
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
130
|
-
s.add_development_dependency(%q<debugger>, [">= 0"])
|
131
|
-
s.add_development_dependency(%q<factory_girl>, [">= 0"])
|
132
|
-
s.add_development_dependency(%q<yard>, [">= 0"])
|
133
|
-
s.add_development_dependency(%q<redcarpet>, [">= 0"])
|
134
|
-
else
|
135
|
-
s.add_dependency(%q<httparty>, [">= 0"])
|
136
|
-
s.add_dependency(%q<hashie>, ["~> 1"])
|
137
|
-
s.add_dependency(%q<json>, [">= 0"])
|
138
|
-
s.add_dependency(%q<rspec>, ["~> 2"])
|
139
|
-
s.add_dependency(%q<jruby-openssl>, [">= 0"])
|
140
|
-
s.add_dependency(%q<webmock>, [">= 0"])
|
141
|
-
s.add_dependency(%q<vcr>, [">= 0"])
|
142
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
143
|
-
s.add_dependency(%q<debugger>, [">= 0"])
|
144
|
-
s.add_dependency(%q<factory_girl>, [">= 0"])
|
145
|
-
s.add_dependency(%q<yard>, [">= 0"])
|
146
|
-
s.add_dependency(%q<redcarpet>, [">= 0"])
|
147
|
-
end
|
148
|
-
else
|
149
|
-
s.add_dependency(%q<httparty>, [">= 0"])
|
150
|
-
s.add_dependency(%q<hashie>, ["~> 1"])
|
151
|
-
s.add_dependency(%q<json>, [">= 0"])
|
152
|
-
s.add_dependency(%q<rspec>, ["~> 2"])
|
153
|
-
s.add_dependency(%q<jruby-openssl>, [">= 0"])
|
154
|
-
s.add_dependency(%q<webmock>, [">= 0"])
|
155
|
-
s.add_dependency(%q<vcr>, [">= 0"])
|
156
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
157
|
-
s.add_dependency(%q<debugger>, [">= 0"])
|
158
|
-
s.add_dependency(%q<factory_girl>, [">= 0"])
|
159
|
-
s.add_dependency(%q<yard>, [">= 0"])
|
160
|
-
s.add_dependency(%q<redcarpet>, [">= 0"])
|
161
|
-
end
|
21
|
+
spec.add_runtime_dependency('httparty')
|
22
|
+
spec.add_runtime_dependency('hashie', '~> 1')
|
23
|
+
spec.add_runtime_dependency('json')
|
162
24
|
end
|
163
|
-
|
data/lib/harvest/api/reports.rb
CHANGED
@@ -1,38 +1,39 @@
|
|
1
1
|
module Harvest
|
2
2
|
module API
|
3
3
|
class Reports < Base
|
4
|
-
|
4
|
+
|
5
5
|
def time_by_project(project, start_date, end_date, options = {})
|
6
6
|
query = {:from => start_date.strftime("%Y%m%d"), :to => end_date.strftime("%Y%m%d")}
|
7
|
-
query[:user_id]
|
8
|
-
query[:billable]
|
7
|
+
query[:user_id] = options[:user].to_i if options[:user]
|
8
|
+
query[:billable] = (options[:billable] ? "yes" : "no") unless options[:billable].nil?
|
9
9
|
query[:updated_since] = options[:updated_since].to_s if options[:updated_since]
|
10
10
|
|
11
11
|
response = request(:get, credentials, "/projects/#{project.to_i}/entries", :query => query)
|
12
12
|
Harvest::TimeEntry.parse(JSON.parse(response.body).map {|h| h["day_entry"]})
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def time_by_user(user, start_date, end_date, options = {})
|
16
16
|
query = {:from => start_date.strftime("%Y%m%d"), :to => end_date.strftime("%Y%m%d")}
|
17
|
-
query[:project_id]
|
18
|
-
query[:billable]
|
17
|
+
query[:project_id] = options[:project].to_i if options[:project]
|
18
|
+
query[:billable] = (options[:billable] ? "yes" : "no") unless options[:billable].nil?
|
19
19
|
query[:updated_since] = options[:updated_since].to_s if options[:updated_since]
|
20
20
|
|
21
21
|
response = request(:get, credentials, "/people/#{user.to_i}/entries", :query => query)
|
22
22
|
Harvest::TimeEntry.parse(JSON.parse(response.body).map {|h| h["day_entry"]})
|
23
23
|
end
|
24
|
-
|
25
|
-
def expenses_by_user(user, start_date, end_date)
|
24
|
+
|
25
|
+
def expenses_by_user(user, start_date, end_date, options = {})
|
26
26
|
query = {:from => start_date.strftime("%Y%m%d"), :to => end_date.strftime("%Y%m%d")}
|
27
|
-
|
27
|
+
query[:updated_since] = options[:updated_since].to_s if options[:updated_since]
|
28
|
+
|
28
29
|
response = request(:get, credentials, "/people/#{user.to_i}/expenses", :query => query)
|
29
30
|
Harvest::Expense.parse(response.parsed_response)
|
30
31
|
end
|
31
|
-
|
32
|
+
|
32
33
|
def projects_by_client(client)
|
33
34
|
response = request(:get, credentials, "/projects?client=#{client.to_i}")
|
34
35
|
Harvest::Project.parse(response.parsed_response)
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
38
|
-
end
|
39
|
+
end
|
data/lib/harvest/base.rb
CHANGED
@@ -4,9 +4,8 @@ module Harvest
|
|
4
4
|
|
5
5
|
# @see Harvest.client
|
6
6
|
# @see Harvest.hardy_client
|
7
|
-
def initialize(subdomain, username, password
|
8
|
-
|
9
|
-
@credentials = Credentials.new(subdomain, username, password, options[:ssl])
|
7
|
+
def initialize(subdomain, username, password)
|
8
|
+
@credentials = Credentials.new(subdomain, username, password)
|
10
9
|
raise InvalidCredentials unless credentials.valid?
|
11
10
|
end
|
12
11
|
|
@@ -31,7 +31,11 @@ module Harvest
|
|
31
31
|
model = api_model.wrap(model)
|
32
32
|
response = request(:post, credentials, "#{api_model.api_path}", :body => model.to_json, :query => of_user_query(user))
|
33
33
|
id = response.headers["location"].match(/\/.*\/(\d+)/)[1]
|
34
|
-
|
34
|
+
if user
|
35
|
+
find(id, user)
|
36
|
+
else
|
37
|
+
find(id)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
|
37
41
|
# Updates an item
|
data/lib/harvest/credentials.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
module Harvest
|
2
2
|
class Credentials
|
3
|
-
attr_accessor :subdomain, :username, :password
|
4
|
-
|
5
|
-
def initialize(subdomain, username, password
|
6
|
-
@subdomain, @username, @password
|
3
|
+
attr_accessor :subdomain, :username, :password
|
4
|
+
|
5
|
+
def initialize(subdomain, username, password)
|
6
|
+
@subdomain, @username, @password = subdomain, username, password
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def valid?
|
10
10
|
!subdomain.nil? && !username.nil? && !password.nil?
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def basic_auth
|
14
14
|
Base64.encode64("#{username}:#{password}").delete("\r\n")
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def host
|
18
|
-
"
|
18
|
+
"https://#{subdomain}.harvestapp.com"
|
19
19
|
end
|
20
20
|
end
|
21
|
-
end
|
21
|
+
end
|
data/lib/harvested.rb
CHANGED
@@ -11,6 +11,7 @@ require 'ext/hash'
|
|
11
11
|
require 'ext/date'
|
12
12
|
require 'ext/time'
|
13
13
|
|
14
|
+
require 'harvest/version'
|
14
15
|
require 'harvest/credentials'
|
15
16
|
require 'harvest/errors'
|
16
17
|
require 'harvest/hardy_client'
|
@@ -23,8 +24,6 @@ require 'harvest/base'
|
|
23
24
|
%w(base account clients contacts projects tasks users task_assignments user_assignments expense_categories expenses time reports invoice_categories invoices invoice_payments).each {|a| require "harvest/api/#{a}"}
|
24
25
|
|
25
26
|
module Harvest
|
26
|
-
VERSION = File.read(File.expand_path(File.join(File.dirname(__FILE__), '..', 'VERSION'))).strip
|
27
|
-
|
28
27
|
class << self
|
29
28
|
|
30
29
|
# Creates a standard client that will raise all errors it encounters
|
@@ -36,7 +35,7 @@ module Harvest
|
|
36
35
|
#
|
37
36
|
# @return [Harvest::Base]
|
38
37
|
def client(subdomain, username, password, options = {})
|
39
|
-
Harvest::Base.new(subdomain, username, password
|
38
|
+
Harvest::Base.new(subdomain, username, password)
|
40
39
|
end
|
41
40
|
|
42
41
|
# Creates a hardy client that will retry common HTTP errors it encounters and sleep() if it determines it is over your rate limit
|
@@ -63,7 +62,7 @@ module Harvest
|
|
63
62
|
# @see Harvest::Base
|
64
63
|
def hardy_client(subdomain, username, password, options = {})
|
65
64
|
retries = options.delete(:retry)
|
66
|
-
Harvest::HardyClient.new(client(subdomain, username, password
|
65
|
+
Harvest::HardyClient.new(client(subdomain, username, password), (retries || 5))
|
67
66
|
end
|
68
67
|
end
|
69
68
|
end
|
@@ -55,13 +55,13 @@ describe 'harvest invoices' do
|
|
55
55
|
invoice = Harvest::Invoice.new(
|
56
56
|
"subject" => "Invoice for Frannie's Widgets",
|
57
57
|
"client_id" => client.id,
|
58
|
-
"issued_at" => "
|
59
|
-
"
|
58
|
+
"issued_at" => "2014-01-01",
|
59
|
+
"due_at_human_format" => "NET 10",
|
60
60
|
"currency" => "United States Dollars - USD",
|
61
61
|
"number" => 1000,
|
62
62
|
"notes" => "Some notes go here",
|
63
|
-
"period_end" => "
|
64
|
-
"period_start" => "
|
63
|
+
"period_end" => "2013-03-31",
|
64
|
+
"period_start" => "2013-02-26",
|
65
65
|
"kind" => "free_form",
|
66
66
|
"state" => "draft",
|
67
67
|
"purchase_order" => nil,
|
@@ -77,12 +77,12 @@ describe 'harvest invoices' do
|
|
77
77
|
invoice.subject.should == "Invoice for Frannie's Widgets"
|
78
78
|
invoice.amount.should == 2400.0
|
79
79
|
invoice.line_items.size.should == 1
|
80
|
-
invoice.due_at.should == "2011-05-31"
|
81
80
|
|
82
81
|
invoice = harvest.invoices.find(invoice.id)
|
83
82
|
invoice.subject.should == "Invoice for Frannie's Widgets"
|
84
83
|
invoice.amount.should == 2400.0
|
85
84
|
invoice.line_items.size.should == 1
|
85
|
+
invoice.due_at.should == "2014-01-11"
|
86
86
|
|
87
87
|
invoices = harvest.invoices.all
|
88
88
|
invoices.count.should == 1
|
@@ -105,7 +105,7 @@ describe 'harvest invoices' do
|
|
105
105
|
invoices = harvest.invoices.all(:updated_since => Date.today)
|
106
106
|
invoices.count.should == 1
|
107
107
|
|
108
|
-
invoices = harvest.invoices.all(:updated_since => '
|
108
|
+
invoices = harvest.invoices.all(:updated_since => '2112-12-31')
|
109
109
|
invoices.count.should == 0
|
110
110
|
|
111
111
|
harvest.invoices.delete(invoice)
|
@@ -69,14 +69,13 @@ describe 'harvest reporting' do
|
|
69
69
|
project = harvest.projects.create("name" => "Expense Reporting Project", "client_id" => client.id)
|
70
70
|
harvest.user_assignments.create("project" => project, "user" => user)
|
71
71
|
|
72
|
-
expense = harvest.expenses.create(
|
72
|
+
expense = harvest.expenses.create({
|
73
73
|
"notes" => "Drive to Chicago",
|
74
74
|
"total_cost" => 75.0,
|
75
75
|
"spent_at" => Time.utc(2009, 12, 28),
|
76
76
|
"expense_category_id" => category.id,
|
77
|
-
"project_id" => project.id
|
78
|
-
|
79
|
-
)
|
77
|
+
"project_id" => project.id
|
78
|
+
}, user.id)
|
80
79
|
|
81
80
|
harvest.reports.expenses_by_user(user, Time.utc(2009, 12, 20), Time.utc(2009,12,30)).first.should == expense
|
82
81
|
|
data/spec/spec_helper.rb
CHANGED
@@ -2,15 +2,19 @@ require 'harvested'
|
|
2
2
|
require 'webmock/rspec'
|
3
3
|
require 'vcr'
|
4
4
|
require 'factory_girl'
|
5
|
+
require 'byebug'
|
5
6
|
|
6
7
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require File.expand_path(f) }
|
7
8
|
|
8
9
|
VCR.configure do |c|
|
9
10
|
c.cassette_library_dir = '.cassettes'
|
10
11
|
c.hook_into :webmock
|
11
|
-
end
|
12
12
|
|
13
|
-
|
13
|
+
c.default_cassette_options = {
|
14
|
+
# force cassettes to re_record when we pass VCR_REFRESH=true
|
15
|
+
re_record_interval: ENV['VCR_REFRESH'] == 'true' ? 0 : nil
|
16
|
+
}
|
17
|
+
end
|
14
18
|
|
15
19
|
FactoryGirl.find_definitions
|
16
20
|
|
@@ -6,18 +6,13 @@ module HarvestedHelpers
|
|
6
6
|
def credentials; HarvestedHelpers.credentials; end
|
7
7
|
|
8
8
|
def self.simple_harvest
|
9
|
-
Harvest.client(credentials["subdomain"], credentials["username"], credentials["password"]
|
9
|
+
Harvest.client(credentials["subdomain"], credentials["username"], credentials["password"])
|
10
10
|
end
|
11
11
|
|
12
|
-
# def connect_to_harvest
|
13
|
-
# @harvest = Harvest.hardy_client(credentials["subdomain"], credentials["username"], credentials["password"], :ssl => true)
|
14
|
-
# end
|
15
|
-
|
16
|
-
# def harvest; @harvest; end
|
17
12
|
def harvest; @harvest ||= HarvestedHelpers.simple_harvest; end
|
18
13
|
|
19
14
|
def hardy_harvest
|
20
|
-
Harvest.hardy_client(credentials["subdomain"], credentials["username"], credentials["password"]
|
15
|
+
Harvest.hardy_client(credentials["subdomain"], credentials["username"], credentials["password"])
|
21
16
|
end
|
22
17
|
|
23
18
|
def self.clean_remote
|
metadata
CHANGED
@@ -1,207 +1,75 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: harvested
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
MS4yLjA=
|
4
|
+
version: 2.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Zach Moazeni
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-
|
11
|
+
date: 2014-04-23 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: httparty
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
16
|
requirements:
|
18
|
-
- -
|
17
|
+
- - ">="
|
19
18
|
- !ruby/object:Gem::Version
|
20
19
|
version: '0'
|
21
20
|
type: :runtime
|
22
21
|
prerelease: false
|
23
22
|
version_requirements: !ruby/object:Gem::Requirement
|
24
23
|
requirements:
|
25
|
-
- -
|
24
|
+
- - ">="
|
26
25
|
- !ruby/object:Gem::Version
|
27
26
|
version: '0'
|
28
27
|
- !ruby/object:Gem::Dependency
|
29
28
|
name: hashie
|
30
29
|
requirement: !ruby/object:Gem::Requirement
|
31
30
|
requirements:
|
32
|
-
- - ~>
|
31
|
+
- - "~>"
|
33
32
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
35
|
-
MQ==
|
33
|
+
version: '1'
|
36
34
|
type: :runtime
|
37
35
|
prerelease: false
|
38
36
|
version_requirements: !ruby/object:Gem::Requirement
|
39
37
|
requirements:
|
40
|
-
- - ~>
|
38
|
+
- - "~>"
|
41
39
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
43
|
-
MQ==
|
40
|
+
version: '1'
|
44
41
|
- !ruby/object:Gem::Dependency
|
45
42
|
name: json
|
46
43
|
requirement: !ruby/object:Gem::Requirement
|
47
44
|
requirements:
|
48
|
-
- -
|
45
|
+
- - ">="
|
49
46
|
- !ruby/object:Gem::Version
|
50
47
|
version: '0'
|
51
48
|
type: :runtime
|
52
49
|
prerelease: false
|
53
50
|
version_requirements: !ruby/object:Gem::Requirement
|
54
51
|
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: '0'
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: rspec
|
60
|
-
requirement: !ruby/object:Gem::Requirement
|
61
|
-
requirements:
|
62
|
-
- - ~>
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: !binary |-
|
65
|
-
Mg==
|
66
|
-
type: :development
|
67
|
-
prerelease: false
|
68
|
-
version_requirements: !ruby/object:Gem::Requirement
|
69
|
-
requirements:
|
70
|
-
- - ~>
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: !binary |-
|
73
|
-
Mg==
|
74
|
-
- !ruby/object:Gem::Dependency
|
75
|
-
name: jruby-openssl
|
76
|
-
requirement: !ruby/object:Gem::Requirement
|
77
|
-
requirements:
|
78
|
-
- - ! '>='
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
version: '0'
|
81
|
-
type: :development
|
82
|
-
prerelease: false
|
83
|
-
version_requirements: !ruby/object:Gem::Requirement
|
84
|
-
requirements:
|
85
|
-
- - ! '>='
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version: '0'
|
88
|
-
- !ruby/object:Gem::Dependency
|
89
|
-
name: webmock
|
90
|
-
requirement: !ruby/object:Gem::Requirement
|
91
|
-
requirements:
|
92
|
-
- - ! '>='
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
version: '0'
|
95
|
-
type: :development
|
96
|
-
prerelease: false
|
97
|
-
version_requirements: !ruby/object:Gem::Requirement
|
98
|
-
requirements:
|
99
|
-
- - ! '>='
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: '0'
|
102
|
-
- !ruby/object:Gem::Dependency
|
103
|
-
name: vcr
|
104
|
-
requirement: !ruby/object:Gem::Requirement
|
105
|
-
requirements:
|
106
|
-
- - ! '>='
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: '0'
|
109
|
-
type: :development
|
110
|
-
prerelease: false
|
111
|
-
version_requirements: !ruby/object:Gem::Requirement
|
112
|
-
requirements:
|
113
|
-
- - ! '>='
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
version: '0'
|
116
|
-
- !ruby/object:Gem::Dependency
|
117
|
-
name: jeweler
|
118
|
-
requirement: !ruby/object:Gem::Requirement
|
119
|
-
requirements:
|
120
|
-
- - ! '>='
|
121
|
-
- !ruby/object:Gem::Version
|
122
|
-
version: '0'
|
123
|
-
type: :development
|
124
|
-
prerelease: false
|
125
|
-
version_requirements: !ruby/object:Gem::Requirement
|
126
|
-
requirements:
|
127
|
-
- - ! '>='
|
128
|
-
- !ruby/object:Gem::Version
|
129
|
-
version: '0'
|
130
|
-
- !ruby/object:Gem::Dependency
|
131
|
-
name: debugger
|
132
|
-
requirement: !ruby/object:Gem::Requirement
|
133
|
-
requirements:
|
134
|
-
- - ! '>='
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
version: '0'
|
137
|
-
type: :development
|
138
|
-
prerelease: false
|
139
|
-
version_requirements: !ruby/object:Gem::Requirement
|
140
|
-
requirements:
|
141
|
-
- - ! '>='
|
142
|
-
- !ruby/object:Gem::Version
|
143
|
-
version: '0'
|
144
|
-
- !ruby/object:Gem::Dependency
|
145
|
-
name: factory_girl
|
146
|
-
requirement: !ruby/object:Gem::Requirement
|
147
|
-
requirements:
|
148
|
-
- - ! '>='
|
149
|
-
- !ruby/object:Gem::Version
|
150
|
-
version: '0'
|
151
|
-
type: :development
|
152
|
-
prerelease: false
|
153
|
-
version_requirements: !ruby/object:Gem::Requirement
|
154
|
-
requirements:
|
155
|
-
- - ! '>='
|
156
|
-
- !ruby/object:Gem::Version
|
157
|
-
version: '0'
|
158
|
-
- !ruby/object:Gem::Dependency
|
159
|
-
name: yard
|
160
|
-
requirement: !ruby/object:Gem::Requirement
|
161
|
-
requirements:
|
162
|
-
- - ! '>='
|
163
|
-
- !ruby/object:Gem::Version
|
164
|
-
version: '0'
|
165
|
-
type: :development
|
166
|
-
prerelease: false
|
167
|
-
version_requirements: !ruby/object:Gem::Requirement
|
168
|
-
requirements:
|
169
|
-
- - ! '>='
|
170
|
-
- !ruby/object:Gem::Version
|
171
|
-
version: '0'
|
172
|
-
- !ruby/object:Gem::Dependency
|
173
|
-
name: redcarpet
|
174
|
-
requirement: !ruby/object:Gem::Requirement
|
175
|
-
requirements:
|
176
|
-
- - ! '>='
|
177
|
-
- !ruby/object:Gem::Version
|
178
|
-
version: '0'
|
179
|
-
type: :development
|
180
|
-
prerelease: false
|
181
|
-
version_requirements: !ruby/object:Gem::Requirement
|
182
|
-
requirements:
|
183
|
-
- - ! '>='
|
52
|
+
- - ">="
|
184
53
|
- !ruby/object:Gem::Version
|
185
54
|
version: '0'
|
186
55
|
description: Harvested wraps the Harvest API concisely without the use of Rails dependencies.
|
187
56
|
More information about the Harvest API can be found on their website (http://www.getharvest.com/api).
|
188
57
|
For support hit up the Mailing List (http://groups.google.com/group/harvested)
|
189
|
-
email:
|
58
|
+
email:
|
59
|
+
- zach.moazeni@gmail.com
|
190
60
|
executables: []
|
191
61
|
extensions: []
|
192
|
-
extra_rdoc_files:
|
193
|
-
- README.md
|
194
|
-
- TODO
|
62
|
+
extra_rdoc_files: []
|
195
63
|
files:
|
196
|
-
- .document
|
197
|
-
- .
|
64
|
+
- ".document"
|
65
|
+
- ".gitignore"
|
66
|
+
- ".ruby-version"
|
198
67
|
- Gemfile
|
199
68
|
- HISTORY
|
200
69
|
- MIT-LICENSE
|
201
70
|
- README.md
|
202
71
|
- Rakefile
|
203
72
|
- TODO
|
204
|
-
- VERSION
|
205
73
|
- examples/basics.rb
|
206
74
|
- examples/clear_account.rb
|
207
75
|
- examples/project_create_script.rb
|
@@ -252,6 +120,7 @@ files:
|
|
252
120
|
- lib/harvest/trackable_project.rb
|
253
121
|
- lib/harvest/user.rb
|
254
122
|
- lib/harvest/user_assignment.rb
|
123
|
+
- lib/harvest/version.rb
|
255
124
|
- lib/harvested.rb
|
256
125
|
- spec/factories.rb
|
257
126
|
- spec/functional/account_spec.rb
|
@@ -285,7 +154,8 @@ files:
|
|
285
154
|
- spec/support/json_examples.rb
|
286
155
|
- spec/test_rubies
|
287
156
|
homepage: http://github.com/zmoazeni/harvested
|
288
|
-
licenses:
|
157
|
+
licenses:
|
158
|
+
- MIT
|
289
159
|
metadata: {}
|
290
160
|
post_install_message:
|
291
161
|
rdoc_options: []
|
@@ -293,18 +163,50 @@ require_paths:
|
|
293
163
|
- lib
|
294
164
|
required_ruby_version: !ruby/object:Gem::Requirement
|
295
165
|
requirements:
|
296
|
-
- -
|
166
|
+
- - ">="
|
297
167
|
- !ruby/object:Gem::Version
|
298
168
|
version: '0'
|
299
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
300
170
|
requirements:
|
301
|
-
- -
|
171
|
+
- - ">="
|
302
172
|
- !ruby/object:Gem::Version
|
303
173
|
version: '0'
|
304
174
|
requirements: []
|
305
175
|
rubyforge_project:
|
306
|
-
rubygems_version: 2.2.
|
176
|
+
rubygems_version: 2.2.2
|
307
177
|
signing_key:
|
308
178
|
specification_version: 4
|
309
179
|
summary: A Ruby Wrapper for the Harvest API http://www.getharvest.com/
|
310
|
-
test_files:
|
180
|
+
test_files:
|
181
|
+
- spec/factories.rb
|
182
|
+
- spec/functional/account_spec.rb
|
183
|
+
- spec/functional/clients_spec.rb
|
184
|
+
- spec/functional/errors_spec.rb
|
185
|
+
- spec/functional/expenses_spec.rb
|
186
|
+
- spec/functional/hardy_client_spec.rb
|
187
|
+
- spec/functional/invoice_payments_spec.rb
|
188
|
+
- spec/functional/invoice_spec.rb
|
189
|
+
- spec/functional/project_spec.rb
|
190
|
+
- spec/functional/reporting_spec.rb
|
191
|
+
- spec/functional/tasks_spec.rb
|
192
|
+
- spec/functional/time_tracking_spec.rb
|
193
|
+
- spec/functional/users_spec.rb
|
194
|
+
- spec/harvest/base_spec.rb
|
195
|
+
- spec/harvest/credentials_spec.rb
|
196
|
+
- spec/harvest/expense_category_spec.rb
|
197
|
+
- spec/harvest/expense_spec.rb
|
198
|
+
- spec/harvest/invoice_payment_spec.rb
|
199
|
+
- spec/harvest/invoice_spec.rb
|
200
|
+
- spec/harvest/project_spec.rb
|
201
|
+
- spec/harvest/task_assignment_spec.rb
|
202
|
+
- spec/harvest/task_spec.rb
|
203
|
+
- spec/harvest/time_entry_spec.rb
|
204
|
+
- spec/harvest/trackable_project_spec.rb
|
205
|
+
- spec/harvest/user_assignment_spec.rb
|
206
|
+
- spec/harvest/user_spec.rb
|
207
|
+
- spec/spec_helper.rb
|
208
|
+
- spec/support/harvest_credentials.example.yml
|
209
|
+
- spec/support/harvested_helpers.rb
|
210
|
+
- spec/support/json_examples.rb
|
211
|
+
- spec/test_rubies
|
212
|
+
has_rdoc:
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
1.2.0
|