elmas 2.4.2 → 2.5.0
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 +4 -4
- data/.rubocop.yml +9 -0
- data/Gemfile +3 -1
- data/Guardfile +6 -4
- data/README.md +15 -4
- data/Rakefile +3 -1
- data/elmas.gemspec +17 -15
- data/lib/elmas.rb +11 -2
- data/lib/elmas/api.rb +2 -0
- data/lib/elmas/client.rb +2 -0
- data/lib/elmas/config.rb +28 -21
- data/lib/elmas/exception.rb +2 -0
- data/lib/elmas/oauth.rb +40 -4
- data/lib/elmas/parser.rb +2 -0
- data/lib/elmas/request.rb +2 -0
- data/lib/elmas/resource.rb +7 -5
- data/lib/elmas/resources/account.rb +27 -24
- data/lib/elmas/resources/aging_receivables_list.rb +8 -6
- data/lib/elmas/resources/bank_account.rb +13 -19
- data/lib/elmas/resources/bank_entry.rb +6 -4
- data/lib/elmas/resources/bank_entry_line.rb +6 -4
- data/lib/elmas/resources/base_entry_line.rb +10 -6
- data/lib/elmas/resources/cash_entry.rb +22 -0
- data/lib/elmas/resources/cash_entry_line.rb +20 -0
- data/lib/elmas/resources/contact.rb +10 -8
- data/lib/elmas/resources/costcenter.rb +4 -2
- data/lib/elmas/resources/costunit.rb +4 -2
- data/lib/elmas/resources/division.rb +26 -0
- data/lib/elmas/resources/document.rb +7 -5
- data/lib/elmas/resources/document_attachment.rb +3 -1
- data/lib/elmas/resources/general_journal_entry.rb +4 -2
- data/lib/elmas/resources/general_journal_entry_line.rb +2 -0
- data/lib/elmas/resources/gl_account.rb +11 -9
- data/lib/elmas/resources/item.rb +21 -18
- data/lib/elmas/resources/item_group.rb +4 -2
- data/lib/elmas/resources/journal.rb +6 -4
- data/lib/elmas/resources/layout.rb +6 -4
- data/lib/elmas/resources/mailbox.rb +6 -4
- data/lib/elmas/resources/payment_condition.rb +9 -7
- data/lib/elmas/resources/printed_sales_invoice.rb +12 -10
- data/lib/elmas/resources/project.rb +11 -19
- data/lib/elmas/resources/purchase_entry.rb +5 -6
- data/lib/elmas/resources/purchase_entry_line.rb +2 -0
- data/lib/elmas/resources/receivables_list.rb +4 -5
- data/lib/elmas/resources/sales_entry.rb +5 -7
- data/lib/elmas/resources/sales_entry_line.rb +2 -0
- data/lib/elmas/resources/sales_invoice.rb +4 -5
- data/lib/elmas/resources/sales_invoice_line.rb +4 -5
- data/lib/elmas/resources/sales_item_prices.rb +4 -5
- data/lib/elmas/resources/sales_order.rb +4 -5
- data/lib/elmas/resources/sales_order_line.rb +4 -5
- data/lib/elmas/resources/shared_sales_attributes.rb +6 -11
- data/lib/elmas/resources/time_transaction.rb +8 -12
- data/lib/elmas/resources/transaction.rb +4 -2
- data/lib/elmas/resources/transaction_line.rb +4 -2
- data/lib/elmas/resources/vat_code.rb +5 -8
- data/lib/elmas/response.rb +5 -2
- data/lib/elmas/result_set.rb +4 -2
- data/lib/elmas/sanitizer.rb +7 -5
- data/lib/elmas/uri.rb +2 -0
- data/lib/elmas/utils.rb +2 -0
- data/lib/elmas/version.rb +4 -2
- metadata +29 -27
- data/lib/elmas/log.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3beb2738aa3a94532e1e4f032a229f87e94aa08
|
4
|
+
data.tar.gz: 37ecf10dae1c0baf831cd221f15c900959d7137b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb404ddad916430568cc25e593d52b06b0e8e35c4b211c78a8587e866c12e8de69b9ff5bee4f2a73659e49c274159cc034c12083592ab7cf146567be1ba3af1c
|
7
|
+
data.tar.gz: 299d31e087f5f2c7847e99cf81cde26e47db46c589216bed196177e75e6e884b69b53a4ea36435897b59d4a69fd3ef0935e523c8d0906cc72580670c1a531f36
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
guard :rspec, cmd: "rspec" do
|
2
4
|
watch(%r{^spec/.+_spec\.rb$})
|
3
5
|
watch(%r{^lib/(.+)\.rb$}) { "spec" }
|
4
|
-
watch(
|
6
|
+
watch("spec/spec_helper.rb") { "spec" }
|
5
7
|
end
|
6
8
|
|
7
|
-
guard :rubocop, all_on_start: false, cli: [
|
9
|
+
guard :rubocop, all_on_start: false, cli: ["--format", "clang", "--rails"] do
|
8
10
|
watch(%r{^spec/.+_spec\.rb$})
|
9
11
|
watch(%r{^lib/(.+)\.rb$})
|
10
|
-
watch(
|
12
|
+
watch("spec/spec_helper.rb")
|
11
13
|
end
|
data/README.md
CHANGED
@@ -18,6 +18,8 @@ Elmas means diamond, but in this case it's an API wrapper for [Exact Online](htt
|
|
18
18
|
* [mipmip](https://github.com/mipmip)
|
19
19
|
* [Bramjetten](https://github.com/Bramjetten)
|
20
20
|
* [LaurensN](https://github.com/LaurensN)
|
21
|
+
* [jdlombardozzi](https://github.com/jdlombardozzi)
|
22
|
+
* [michielverkoijen](https://github.com/michielverkoijen)
|
21
23
|
|
22
24
|
Thanks for helping! If you want to contribute read through this readme how to!
|
23
25
|
|
@@ -75,11 +77,8 @@ So combining all of this results in
|
|
75
77
|
Elmas.configure do |config|
|
76
78
|
config.client_id = ENV['CLIENT_ID']
|
77
79
|
config.client_secret = ENV['CLIENT_SECRET']
|
78
|
-
|
79
|
-
Elmas.configure do |config|
|
80
|
+
config.redirect_uri = ENV['REDIRECT_URI']
|
80
81
|
config.access_token = Elmas.authorize(ENV['EXACT_USER_NAME'], ENV['EXACT_PASSWORD']).access_token
|
81
|
-
end
|
82
|
-
Elmas.configure do |config|
|
83
82
|
config.division = Elmas.authorize_division
|
84
83
|
end
|
85
84
|
```
|
@@ -98,6 +97,18 @@ unless Elmas.authorized?
|
|
98
97
|
end
|
99
98
|
```
|
100
99
|
|
100
|
+
### Logger
|
101
|
+
|
102
|
+
The default logger is STDOUT. A custom logger can be be configured.
|
103
|
+
```ruby
|
104
|
+
dir = File.dirname("./tmp/errors.log")
|
105
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
106
|
+
|
107
|
+
Elmas.configure do |config|
|
108
|
+
config.logger = ::Logger.new("./tmp/errors.log", "daily")
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
101
112
|
## Accessing the API
|
102
113
|
|
103
114
|
We can retrieve data from the API using the following syntax.
|
data/Rakefile
CHANGED
data/elmas.gemspec
CHANGED
@@ -1,37 +1,39 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require "elmas/version"
|
5
6
|
|
7
|
+
# rubocop:disable Metrics/BlockLength
|
6
8
|
Gem::Specification.new do |spec|
|
7
9
|
spec.name = "elmas"
|
8
10
|
spec.authors = ["Marthyn"]
|
9
11
|
spec.email = ["MarthynOlthof@hoppinger.nl"]
|
10
12
|
|
11
|
-
spec.summary =
|
13
|
+
spec.summary = "API wrapper for Exact Online"
|
12
14
|
spec.homepage = "https://github.com/exactonline/exactonline-api-ruby-client"
|
13
|
-
spec.licenses = %w
|
15
|
+
spec.licenses = %w[MIT]
|
14
16
|
|
15
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
|
16
|
-
spec.require_paths = %w
|
18
|
+
spec.require_paths = %w[lib]
|
17
19
|
spec.version = Elmas::Version.to_s
|
18
20
|
|
21
|
+
spec.add_dependency "activeresource"
|
22
|
+
spec.add_dependency "activesupport"
|
19
23
|
spec.add_dependency "faraday", [">= 0.12.1"]
|
20
24
|
spec.add_dependency "mechanize", ">= 2.7.5"
|
21
|
-
spec.add_dependency "activesupport"
|
22
|
-
spec.add_dependency "activeresource"
|
23
25
|
|
24
26
|
spec.add_development_dependency "bundler"
|
27
|
+
spec.add_development_dependency "dotenv"
|
28
|
+
spec.add_development_dependency "guard-rspec"
|
29
|
+
spec.add_development_dependency "guard-rubocop"
|
30
|
+
spec.add_development_dependency "listen"
|
31
|
+
spec.add_development_dependency "mutant-rspec"
|
25
32
|
spec.add_development_dependency "rake"
|
26
33
|
spec.add_development_dependency "rspec"
|
34
|
+
spec.add_development_dependency "ruby_dep"
|
35
|
+
spec.add_development_dependency "rubycritic"
|
27
36
|
spec.add_development_dependency "simplecov"
|
28
37
|
spec.add_development_dependency "simplecov-rcov"
|
29
38
|
spec.add_development_dependency "webmock"
|
30
|
-
spec.add_development_dependency "rubycritic"
|
31
|
-
spec.add_development_dependency "guard-rspec"
|
32
|
-
spec.add_development_dependency "guard-rubocop"
|
33
|
-
spec.add_development_dependency "listen"
|
34
|
-
spec.add_development_dependency "ruby_dep"
|
35
|
-
spec.add_development_dependency "mutant-rspec"
|
36
|
-
spec.add_development_dependency "dotenv"
|
37
39
|
end
|
data/lib/elmas.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "elmas/version"
|
2
4
|
require "elmas/api"
|
3
5
|
require "elmas/config"
|
4
6
|
require "elmas/response"
|
5
7
|
require "elmas/client"
|
6
|
-
require "elmas/log"
|
7
8
|
require "elmas/resource"
|
8
9
|
require "elmas/result_set"
|
9
10
|
require "elmas/sanitizer"
|
@@ -44,10 +45,10 @@ require "elmas/resources/vat_code"
|
|
44
45
|
require "elmas/resources/general_journal_entry"
|
45
46
|
require "elmas/resources/general_journal_entry_line"
|
46
47
|
require "elmas/resources/payment_condition"
|
48
|
+
require "elmas/resources/division"
|
47
49
|
|
48
50
|
module Elmas
|
49
51
|
extend Config
|
50
|
-
extend Log
|
51
52
|
|
52
53
|
def self.client(options = {})
|
53
54
|
Elmas::Client.new(options)
|
@@ -63,4 +64,12 @@ module Elmas
|
|
63
64
|
def self.respond_to?(method, include_all = false)
|
64
65
|
client.respond_to?(method, include_all) || super
|
65
66
|
end
|
67
|
+
|
68
|
+
def self.info(msg)
|
69
|
+
logger.info(msg)
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.error(msg)
|
73
|
+
logger.error(msg)
|
74
|
+
end
|
66
75
|
end
|
data/lib/elmas/api.rb
CHANGED
data/lib/elmas/client.rb
CHANGED
data/lib/elmas/config.rb
CHANGED
@@ -1,29 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "faraday"
|
2
4
|
require "active_resource/threadsafe_attributes"
|
5
|
+
require "logger"
|
3
6
|
|
4
7
|
module Elmas
|
5
8
|
module Config
|
6
9
|
include ThreadsafeAttributes
|
7
10
|
# An array of valid keys in the options hash
|
8
|
-
VALID_OPTIONS_KEYS = [
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
VALID_OPTIONS_KEYS = %i[
|
12
|
+
access_token
|
13
|
+
adapter
|
14
|
+
client_id
|
15
|
+
client_secret
|
16
|
+
connection_options
|
17
|
+
redirect_uri
|
18
|
+
response_format
|
19
|
+
user_agent
|
20
|
+
endpoint
|
21
|
+
division
|
22
|
+
base_url
|
23
|
+
refresh_token
|
24
|
+
logger
|
21
25
|
].freeze
|
22
26
|
|
23
27
|
# By default, don't set a user access token
|
24
|
-
DEFAULT_ACCESS_TOKEN = ""
|
28
|
+
DEFAULT_ACCESS_TOKEN = ""
|
25
29
|
|
26
|
-
DEFAULT_REFRESH_TOKEN = ""
|
30
|
+
DEFAULT_REFRESH_TOKEN = ""
|
27
31
|
|
28
32
|
# The adapter that will be used to connect if none is set
|
29
33
|
#
|
@@ -31,27 +35,27 @@ module Elmas
|
|
31
35
|
DEFAULT_ADAPTER = Faraday.default_adapter
|
32
36
|
|
33
37
|
# By default, client id should be set in .env
|
34
|
-
DEFAULT_CLIENT_ID = ""
|
38
|
+
DEFAULT_CLIENT_ID = ""
|
35
39
|
|
36
40
|
# By default, client secret should be set in .env
|
37
|
-
DEFAULT_CLIENT_SECRET = ""
|
41
|
+
DEFAULT_CLIENT_SECRET = ""
|
38
42
|
|
39
43
|
# By default, don't set any connection options
|
40
44
|
DEFAULT_CONNECTION_OPTIONS = {}.freeze
|
41
45
|
|
42
|
-
DEFAULT_BASE_URL = "https://start.exactonline.nl"
|
46
|
+
DEFAULT_BASE_URL = "https://start.exactonline.nl"
|
43
47
|
|
44
48
|
# The endpoint that will be used to connect if none is set
|
45
|
-
DEFAULT_ENDPOINT = "api/v1"
|
49
|
+
DEFAULT_ENDPOINT = "api/v1"
|
46
50
|
|
47
51
|
# the division code you want to connect with
|
48
|
-
DEFAULT_DIVISION = ""
|
52
|
+
DEFAULT_DIVISION = ""
|
49
53
|
|
50
54
|
# The response format appended to the path and sent in the 'Accept' header if none is set
|
51
55
|
#
|
52
56
|
DEFAULT_FORMAT = :json
|
53
57
|
|
54
|
-
DEFAULT_REDIRECT_URI = "https://www.getpostman.com/oauth2/callback"
|
58
|
+
DEFAULT_REDIRECT_URI = "https://www.getpostman.com/oauth2/callback"
|
55
59
|
|
56
60
|
# By default, don't set user agent
|
57
61
|
DEFAULT_USER_AGENT = nil
|
@@ -59,6 +63,8 @@ module Elmas
|
|
59
63
|
# An array of valid request/response formats
|
60
64
|
VALID_FORMATS = [:json].freeze
|
61
65
|
|
66
|
+
DEFAULT_LOGGER = ::Logger.new(STDOUT)
|
67
|
+
|
62
68
|
# @private
|
63
69
|
threadsafe_attribute(*VALID_OPTIONS_KEYS)
|
64
70
|
|
@@ -93,6 +99,7 @@ module Elmas
|
|
93
99
|
self.response_format = DEFAULT_FORMAT
|
94
100
|
self.user_agent = DEFAULT_USER_AGENT
|
95
101
|
self.refresh_token = DEFAULT_REFRESH_TOKEN
|
102
|
+
self.logger = DEFAULT_LOGGER
|
96
103
|
end
|
97
104
|
end
|
98
105
|
end
|
data/lib/elmas/exception.rb
CHANGED
data/lib/elmas/oauth.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "mechanize"
|
2
4
|
require "uri"
|
3
5
|
require "json"
|
@@ -7,6 +9,7 @@ require File.expand_path("../response", __FILE__)
|
|
7
9
|
|
8
10
|
# from https://developers.exactonline.com/#Example retrieve access token.html
|
9
11
|
module Elmas
|
12
|
+
# rubocop:disable Metrics/ModuleLength
|
10
13
|
module OAuth
|
11
14
|
def authorize(user_name, password, options = {})
|
12
15
|
agent = Mechanize.new
|
@@ -18,6 +21,15 @@ module Elmas
|
|
18
21
|
OauthResponse.new(get_access_token(code))
|
19
22
|
end
|
20
23
|
|
24
|
+
def refresh_authorization
|
25
|
+
OauthResponse.new(get_refresh_token(refresh_token)).tap do |response|
|
26
|
+
Elmas.configure do |config|
|
27
|
+
config.access_token = response.access_token
|
28
|
+
config.refresh_token = response.refresh_token
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
21
33
|
def authorized?
|
22
34
|
# Do a test call, return false if 401 or any error code
|
23
35
|
get("/Current/Me", no_division: true)
|
@@ -32,13 +44,10 @@ module Elmas
|
|
32
44
|
|
33
45
|
def auto_authorize
|
34
46
|
Elmas.configure do |config|
|
47
|
+
config.redirect_uri = ENV["REDIRECT_URI"]
|
35
48
|
config.client_id = ENV["CLIENT_ID"]
|
36
49
|
config.client_secret = ENV["CLIENT_SECRET"]
|
37
|
-
end
|
38
|
-
Elmas.configure do |config|
|
39
50
|
config.access_token = Elmas.authorize(ENV["EXACT_USER_NAME"], ENV["EXACT_PASSWORD"]).access_token
|
40
|
-
end
|
41
|
-
Elmas.configure do |config|
|
42
51
|
config.division = Elmas.authorize_division
|
43
52
|
end
|
44
53
|
end
|
@@ -67,6 +76,23 @@ module Elmas
|
|
67
76
|
end
|
68
77
|
end
|
69
78
|
|
79
|
+
# Return an access token from authorization via refresh token
|
80
|
+
def get_refresh_token(refresh_token)
|
81
|
+
conn = Faraday.new(url: config[:base_url]) do |faraday|
|
82
|
+
faraday.request :url_encoded
|
83
|
+
faraday.adapter Faraday.default_adapter
|
84
|
+
end
|
85
|
+
|
86
|
+
params = refresh_access_token_params(refresh_token)
|
87
|
+
|
88
|
+
conn.post do |req|
|
89
|
+
req.url "/api/oauth2/token"
|
90
|
+
req.body = params
|
91
|
+
req.headers["Accept"] = "application/json"
|
92
|
+
req.headers["Content-Type"] = "application/x-www-form-urlencoded"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
70
96
|
private
|
71
97
|
|
72
98
|
def login(agent, user_name, password, options)
|
@@ -81,6 +107,7 @@ module Elmas
|
|
81
107
|
|
82
108
|
def allow_access(agent)
|
83
109
|
return if agent.page.uri.to_s.include?("getpostman")
|
110
|
+
return if agent.page.uri.to_s.include?(redirect_uri)
|
84
111
|
form = agent.page.form_with(id: "PublicOAuth2Form")
|
85
112
|
button = form.button_with(id: "AllowButton")
|
86
113
|
agent.submit(form, button)
|
@@ -101,6 +128,15 @@ module Elmas
|
|
101
128
|
redirect_uri: redirect_uri
|
102
129
|
}
|
103
130
|
end
|
131
|
+
|
132
|
+
def refresh_access_token_params(code)
|
133
|
+
{
|
134
|
+
client_id: client_id,
|
135
|
+
client_secret: client_secret,
|
136
|
+
grant_type: "refresh_token",
|
137
|
+
refresh_token: code
|
138
|
+
}
|
139
|
+
end
|
104
140
|
end
|
105
141
|
end
|
106
142
|
|
data/lib/elmas/parser.rb
CHANGED
data/lib/elmas/request.rb
CHANGED
data/lib/elmas/resource.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require File.expand_path("../utils", __FILE__)
|
2
4
|
require File.expand_path("../exception", __FILE__)
|
3
5
|
require File.expand_path("../uri", __FILE__)
|
@@ -24,8 +26,8 @@ module Elmas
|
|
24
26
|
def find_all(options = {})
|
25
27
|
@order_by = options[:order_by]
|
26
28
|
@select = options[:select]
|
27
|
-
response = get(uri([
|
28
|
-
response
|
29
|
+
response = get(uri(%i[order select]))
|
30
|
+
response&.results
|
29
31
|
end
|
30
32
|
|
31
33
|
# Pass filters in an array, for example 'filters: [:id, :name]'
|
@@ -33,14 +35,14 @@ module Elmas
|
|
33
35
|
@filters = options[:filters]
|
34
36
|
@order_by = options[:order_by]
|
35
37
|
@select = options[:select]
|
36
|
-
response = get(uri([
|
37
|
-
response
|
38
|
+
response = get(uri(%i[order select filters]))
|
39
|
+
response&.results
|
38
40
|
end
|
39
41
|
|
40
42
|
def find
|
41
43
|
return nil unless id?
|
42
44
|
response = get(uri([:id]))
|
43
|
-
response
|
45
|
+
response&.results&.first
|
44
46
|
end
|
45
47
|
|
46
48
|
# Normally use the url method (which applies the filters) but sometimes you only want to use the base path or other paths
|