fakturoid 0.2.0 → 0.4.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 +5 -5
- data/.github/workflows/rubocop.yml +20 -0
- data/.github/workflows/tests.yml +27 -0
- data/.rubocop.yml +54 -12
- data/.ruby-version +1 -1
- data/CHANGELOG.md +55 -0
- data/Gemfile +3 -1
- data/README.md +46 -38
- data/fakturoid.gemspec +1 -1
- data/lib/fakturoid/api/arguments.rb +3 -1
- data/lib/fakturoid/api/http_methods.rb +2 -0
- data/lib/fakturoid/api.rb +4 -2
- data/lib/fakturoid/client/account.rb +3 -1
- data/lib/fakturoid/client/bank_account.rb +3 -1
- data/lib/fakturoid/client/event.rb +4 -2
- data/lib/fakturoid/client/expense.rb +16 -7
- data/lib/fakturoid/client/generator.rb +6 -4
- data/lib/fakturoid/client/invoice.rb +19 -11
- data/lib/fakturoid/client/number_format.rb +11 -0
- data/lib/fakturoid/client/subject.rb +10 -4
- data/lib/fakturoid/client/todo.rb +3 -1
- data/lib/fakturoid/client/user.rb +4 -2
- data/lib/fakturoid/client.rb +12 -9
- data/lib/fakturoid/config.rb +14 -2
- data/lib/fakturoid/connection.rb +11 -3
- data/lib/fakturoid/railtie.rb +2 -0
- data/lib/fakturoid/request.rb +5 -1
- data/lib/fakturoid/response.rb +21 -19
- data/lib/fakturoid/version.rb +3 -1
- data/lib/fakturoid.rb +14 -12
- data/test/api_test.rb +12 -10
- data/test/config_test.rb +23 -21
- data/test/request_test.rb +8 -6
- data/test/response_test.rb +68 -66
- data/test/test_helper.rb +8 -6
- metadata +10 -7
@@ -1,22 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fakturoid
|
2
4
|
module Client
|
3
5
|
class Invoice < Fakturoid::Api
|
6
|
+
INDEX_PARAMS = [:page, :since, :until, :updated_since, :updated_until, :number, :status, :subject_id, :custom_id].freeze
|
7
|
+
|
4
8
|
def self.all(params = {})
|
5
|
-
request_params = permit_params(params,
|
9
|
+
request_params = permit_params(params, *INDEX_PARAMS) || {}
|
6
10
|
|
7
|
-
get_request(
|
11
|
+
get_request("invoices.json", request_params: request_params)
|
8
12
|
end
|
9
13
|
|
10
14
|
def self.regular(params = {})
|
11
|
-
request_params = permit_params(params,
|
15
|
+
request_params = permit_params(params, *INDEX_PARAMS) || {}
|
12
16
|
|
13
|
-
get_request(
|
17
|
+
get_request("invoices/regular.json", request_params: request_params)
|
14
18
|
end
|
15
19
|
|
16
20
|
def self.proforma(params = {})
|
17
|
-
request_params = permit_params(params,
|
21
|
+
request_params = permit_params(params, *INDEX_PARAMS) || {}
|
18
22
|
|
19
|
-
get_request(
|
23
|
+
get_request("invoices/proforma.json", request_params: request_params)
|
20
24
|
end
|
21
25
|
|
22
26
|
def self.find(id)
|
@@ -24,18 +28,22 @@ module Fakturoid
|
|
24
28
|
get_request("invoices/#{id}.json")
|
25
29
|
end
|
26
30
|
|
27
|
-
def self.search(query)
|
31
|
+
def self.search(query, params = {})
|
28
32
|
validate_search_query(query)
|
29
|
-
|
33
|
+
|
34
|
+
request_params = permit_params(params, :page)
|
35
|
+
request_params[:query] = query
|
36
|
+
|
37
|
+
get_request("invoices/search.json", request_params: request_params)
|
30
38
|
end
|
31
39
|
|
32
40
|
def self.download_pdf(id)
|
33
41
|
validate_numerical_id(id)
|
34
|
-
get_request("invoices/#{id}/download.pdf", headers: { content_type:
|
42
|
+
get_request("invoices/#{id}/download.pdf", headers: { content_type: "application/pdf" })
|
35
43
|
end
|
36
44
|
|
37
45
|
def self.fire(id, event, params = {})
|
38
|
-
request_params = permit_params(params, :paid_at) || {}
|
46
|
+
request_params = permit_params(params, :paid_at, :paid_amount, :variable_symbol, :bank_account_id) || {}
|
39
47
|
request_params[:event] = event
|
40
48
|
|
41
49
|
validate_numerical_id(id)
|
@@ -48,7 +56,7 @@ module Fakturoid
|
|
48
56
|
end
|
49
57
|
|
50
58
|
def self.create(payload = {})
|
51
|
-
post_request(
|
59
|
+
post_request("invoices.json", payload: payload)
|
52
60
|
end
|
53
61
|
|
54
62
|
def self.update(id, payload = {})
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fakturoid
|
2
4
|
module Client
|
3
5
|
class Subject < Fakturoid::Api
|
4
6
|
def self.all(params = {})
|
5
7
|
request_params = permit_params(params, :page, :since, :updated_since, :custom_id) || {}
|
6
8
|
|
7
|
-
get_request(
|
9
|
+
get_request("subjects.json", request_params: request_params)
|
8
10
|
end
|
9
11
|
|
10
12
|
def self.find(id)
|
@@ -12,13 +14,17 @@ module Fakturoid
|
|
12
14
|
get_request("subjects/#{id}.json")
|
13
15
|
end
|
14
16
|
|
15
|
-
def self.search(query)
|
17
|
+
def self.search(query, params = {})
|
16
18
|
validate_search_query(query)
|
17
|
-
|
19
|
+
|
20
|
+
request_params = permit_params(params, :page)
|
21
|
+
request_params[:query] = query
|
22
|
+
|
23
|
+
get_request("subjects/search.json", request_params: request_params)
|
18
24
|
end
|
19
25
|
|
20
26
|
def self.create(payload = {})
|
21
|
-
post_request(
|
27
|
+
post_request("subjects.json", payload: payload)
|
22
28
|
end
|
23
29
|
|
24
30
|
def self.update(id, payload = {})
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fakturoid
|
2
4
|
module Client
|
3
5
|
class Todo < Fakturoid::Api
|
4
6
|
def self.all(params = {})
|
5
7
|
request_params = permit_params(params, :page, :since) || {}
|
6
8
|
|
7
|
-
get_request(
|
9
|
+
get_request("todos.json", request_params: request_params)
|
8
10
|
end
|
9
11
|
|
10
12
|
def self.toggle_completion(id)
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fakturoid
|
2
4
|
module Client
|
3
5
|
class User < Api
|
4
6
|
def self.current
|
5
|
-
get_request(
|
7
|
+
get_request("user.json", url: Fakturoid::Api.config.endpoint_without_account)
|
6
8
|
end
|
7
9
|
|
8
10
|
def self.find(id)
|
@@ -11,7 +13,7 @@ module Fakturoid
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def self.all
|
14
|
-
get_request(
|
16
|
+
get_request("users.json")
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
data/lib/fakturoid/client.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fakturoid/client/account"
|
4
|
+
require "fakturoid/client/bank_account"
|
5
|
+
require "fakturoid/client/number_format"
|
6
|
+
require "fakturoid/client/user"
|
7
|
+
require "fakturoid/client/subject"
|
8
|
+
require "fakturoid/client/invoice"
|
9
|
+
require "fakturoid/client/expense"
|
10
|
+
require "fakturoid/client/generator"
|
11
|
+
require "fakturoid/client/event"
|
12
|
+
require "fakturoid/client/todo"
|
data/lib/fakturoid/config.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fakturoid
|
2
4
|
class Config
|
3
5
|
attr_accessor :email, :api_key, :account
|
4
6
|
attr_writer :user_agent
|
5
7
|
|
6
|
-
ENDPOINT =
|
8
|
+
ENDPOINT = "https://app.fakturoid.cz/api/v2"
|
7
9
|
|
8
10
|
def initialize(&_block)
|
9
11
|
yield self
|
10
12
|
end
|
11
13
|
|
12
14
|
def user_agent
|
13
|
-
if @user_agent.nil? || @user_agent.empty?
|
15
|
+
if !defined?(@user_agent) || @user_agent.nil? || @user_agent.empty?
|
14
16
|
"Fakturoid ruby gem (#{email})"
|
15
17
|
else
|
16
18
|
@user_agent
|
@@ -24,5 +26,15 @@ module Fakturoid
|
|
24
26
|
def endpoint_without_account
|
25
27
|
ENDPOINT
|
26
28
|
end
|
29
|
+
|
30
|
+
def faraday_v1?
|
31
|
+
major_faraday_version == "1"
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def major_faraday_version
|
37
|
+
@major_faraday_version ||= Faraday::VERSION.split(".").first
|
38
|
+
end
|
27
39
|
end
|
28
40
|
end
|
data/lib/fakturoid/connection.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fakturoid
|
2
4
|
module Connection
|
5
|
+
DEFAULT_CONTENT_TYPE = "application/json"
|
3
6
|
|
4
7
|
def default_options(options = {})
|
5
|
-
content_type = options[:headers] && options[:headers][:content_type]
|
6
8
|
{
|
7
9
|
headers: {
|
8
|
-
content_type: content_type ||
|
10
|
+
content_type: options.dig(:headers, :content_type) || DEFAULT_CONTENT_TYPE,
|
9
11
|
user_agent: Fakturoid::Api.config.user_agent
|
10
12
|
},
|
11
13
|
url: options[:url] || Fakturoid::Api.config.endpoint
|
@@ -14,7 +16,13 @@ module Fakturoid
|
|
14
16
|
|
15
17
|
def connection(options = {})
|
16
18
|
@connection = Faraday.new default_options(options)
|
17
|
-
|
19
|
+
|
20
|
+
# https://lostisland.github.io/faraday/middleware/authentication
|
21
|
+
if Fakturoid::Api.config.faraday_v1?
|
22
|
+
@connection.request :basic_auth, Fakturoid::Api.config.email, Fakturoid::Api.config.api_key
|
23
|
+
else
|
24
|
+
@connection.request :authorization, :basic, Fakturoid::Api.config.email, Fakturoid::Api.config.api_key
|
25
|
+
end
|
18
26
|
|
19
27
|
@connection
|
20
28
|
end
|
data/lib/fakturoid/railtie.rb
CHANGED
data/lib/fakturoid/request.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fakturoid
|
2
4
|
class Request
|
3
5
|
include Connection
|
4
6
|
|
5
7
|
attr_reader :method, :path, :caller
|
6
|
-
|
8
|
+
|
9
|
+
HTTP_METHODS = [:get, :post, :patch, :delete].freeze
|
7
10
|
|
8
11
|
def initialize(method, path, caller)
|
9
12
|
@method = method
|
@@ -19,6 +22,7 @@ module Fakturoid
|
|
19
22
|
http_connection = connection(params)
|
20
23
|
response = http_connection.send(method) do |req|
|
21
24
|
req.url path, request_params
|
25
|
+
req.headers["X-Client-Env"] = "Ruby #{RUBY_VERSION}"
|
22
26
|
req.body = MultiJson.dump(params[:payload]) if params.key?(:payload)
|
23
27
|
end
|
24
28
|
Response.new(response, caller, method)
|
data/lib/fakturoid/response.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fakturoid
|
2
4
|
class Response
|
3
5
|
attr_reader :response, :caller, :env, :body, :request_method
|
@@ -15,11 +17,11 @@ module Fakturoid
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def status_code
|
18
|
-
env[
|
20
|
+
env["status"]
|
19
21
|
end
|
20
22
|
|
21
23
|
def json?
|
22
|
-
env.request_headers[
|
24
|
+
env.request_headers["Content-Type"] == "application/json"
|
23
25
|
end
|
24
26
|
|
25
27
|
def headers
|
@@ -35,23 +37,23 @@ module Fakturoid
|
|
35
37
|
def handle_response
|
36
38
|
case status_code
|
37
39
|
when 400
|
38
|
-
raise error(UserAgentError,
|
39
|
-
raise error(PaginationError,
|
40
|
-
when 401 then raise error(AuthenticationError,
|
41
|
-
when 402 then raise error(BlockedAccountError,
|
42
|
-
when 403
|
43
|
-
raise error(DestroySubjectError,
|
44
|
-
raise error(SubjectLimitError,
|
45
|
-
raise error(GeneratorLimitError,
|
46
|
-
raise error(UnsupportedFeatureError,
|
47
|
-
when 404 then raise error(RecordNotFoundError,
|
48
|
-
when 415 then raise error(ContentTypeError,
|
49
|
-
when 422 then raise error(InvalidRecordError,
|
50
|
-
when 429 then raise error(RateLimitError,
|
51
|
-
when 503 then raise error(ReadOnlySiteError,
|
40
|
+
raise error(UserAgentError, "User-Agent header missing") if env.request_headers["User-Agent"].nil? || env.request_headers["User-Agent"].empty?
|
41
|
+
raise error(PaginationError, "Page does not exist")
|
42
|
+
when 401 then raise error(AuthenticationError, "Authentification failed")
|
43
|
+
when 402 then raise error(BlockedAccountError, "Account is blocked")
|
44
|
+
when 403
|
45
|
+
raise error(DestroySubjectError, "Cannot destroy subject with invoices") if caller == Client::Subject && request_method == :delete
|
46
|
+
raise error(SubjectLimitError, "Subject limit for account reached") if caller == Client::Subject && request_method == :post
|
47
|
+
raise error(GeneratorLimitError, "Recurring generator limit for account reached") if caller == Client::Generator
|
48
|
+
raise error(UnsupportedFeatureError, "Feature unavailable for account plan")
|
49
|
+
when 404 then raise error(RecordNotFoundError, "Record not found")
|
50
|
+
when 415 then raise error(ContentTypeError, "Unsupported Content-Type")
|
51
|
+
when 422 then raise error(InvalidRecordError, "Invalid record")
|
52
|
+
when 429 then raise error(RateLimitError, "Rate limit reached")
|
53
|
+
when 503 then raise error(ReadOnlySiteError, "Fakturoid is in read only state")
|
52
54
|
else
|
53
|
-
raise error(ServerError,
|
54
|
-
raise error(ClientError,
|
55
|
+
raise error(ServerError, "Server error") if status_code >= 500
|
56
|
+
raise error(ClientError, "Client error") if status_code >= 400
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
@@ -72,7 +74,7 @@ module Fakturoid
|
|
72
74
|
end
|
73
75
|
|
74
76
|
def body_has_key?(key)
|
75
|
-
body
|
77
|
+
body.is_a?(Hash) && body.key?(key.to_s)
|
76
78
|
end
|
77
79
|
end
|
78
80
|
end
|
data/lib/fakturoid/version.rb
CHANGED
data/lib/fakturoid.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
|
5
|
-
require
|
6
|
-
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
require "multi_json"
|
5
|
+
require "faraday"
|
6
|
+
|
7
|
+
require "fakturoid/config"
|
8
|
+
require "fakturoid/connection"
|
9
|
+
require "fakturoid/request"
|
10
|
+
require "fakturoid/response"
|
11
|
+
require "fakturoid/api"
|
12
|
+
require "fakturoid/client"
|
13
|
+
require "fakturoid/version"
|
14
|
+
require "fakturoid/railtie" if defined?(::Rails)
|
13
15
|
|
14
16
|
module Fakturoid
|
15
17
|
class ApiError < StandardError
|
data/test/api_test.rb
CHANGED
@@ -1,22 +1,24 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
2
4
|
|
3
5
|
class Fakturoid::ApiTest < Fakturoid::TestCase
|
4
|
-
should
|
5
|
-
hash = { page: 4, number:
|
6
|
+
should "permit only required arguments" do
|
7
|
+
hash = { page: 4, number: "2015-0015", account: 15 }
|
6
8
|
permitted_params = Fakturoid::Api.permit_params(hash, :page, :number, :status)
|
7
|
-
assert_equal({ page: 4, number:
|
9
|
+
assert_equal({ page: 4, number: "2015-0015" }, permitted_params)
|
8
10
|
end
|
9
11
|
|
10
|
-
should
|
12
|
+
should "raise argument error if id is in wrong format" do
|
11
13
|
assert_raises(ArgumentError) { Fakturoid::Api.validate_numerical_id(nil) }
|
12
|
-
assert_raises(ArgumentError) { Fakturoid::Api.validate_numerical_id(
|
14
|
+
assert_raises(ArgumentError) { Fakturoid::Api.validate_numerical_id("nil") }
|
13
15
|
assert Fakturoid::Api.validate_numerical_id(15)
|
14
|
-
assert Fakturoid::Api.validate_numerical_id(
|
16
|
+
assert Fakturoid::Api.validate_numerical_id("15")
|
15
17
|
end
|
16
18
|
|
17
|
-
should
|
19
|
+
should "raise argument error if search query is not given" do
|
18
20
|
assert_raises(ArgumentError) { Fakturoid::Api.validate_search_query(nil) }
|
19
|
-
assert_raises(ArgumentError) { Fakturoid::Api.validate_search_query(
|
20
|
-
assert Fakturoid::Api.validate_search_query(
|
21
|
+
assert_raises(ArgumentError) { Fakturoid::Api.validate_search_query("") }
|
22
|
+
assert Fakturoid::Api.validate_search_query("Company name")
|
21
23
|
end
|
22
24
|
end
|
data/test/config_test.rb
CHANGED
@@ -1,38 +1,40 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
2
4
|
|
3
5
|
class Fakturoid::ConfigTest < Fakturoid::TestCase
|
4
|
-
should
|
6
|
+
should "configure with block param" do
|
5
7
|
config = Fakturoid::Config.new do |c|
|
6
|
-
c.email =
|
7
|
-
c.api_key =
|
8
|
-
c.account =
|
9
|
-
c.user_agent =
|
8
|
+
c.email = "test@email.cz"
|
9
|
+
c.api_key = "XXXXXXXXXXX"
|
10
|
+
c.account = "testaccount"
|
11
|
+
c.user_agent = "My test app (test@email.cz)"
|
10
12
|
end
|
11
13
|
|
12
|
-
assert_equal
|
13
|
-
assert_equal
|
14
|
-
assert_equal
|
15
|
-
assert_equal
|
14
|
+
assert_equal "test@email.cz", config.email
|
15
|
+
assert_equal "XXXXXXXXXXX", config.api_key
|
16
|
+
assert_equal "testaccount", config.account
|
17
|
+
assert_equal "My test app (test@email.cz)", config.user_agent
|
16
18
|
end
|
17
19
|
|
18
|
-
should
|
20
|
+
should "use default user agent" do
|
19
21
|
config = Fakturoid::Config.new do |c|
|
20
|
-
c.email =
|
21
|
-
c.api_key =
|
22
|
-
c.account =
|
22
|
+
c.email = "test@email.cz"
|
23
|
+
c.api_key = "XXXXXXXXXXX"
|
24
|
+
c.account = "testaccount"
|
23
25
|
end
|
24
26
|
|
25
|
-
assert_equal
|
27
|
+
assert_equal "Fakturoid ruby gem (test@email.cz)", config.user_agent
|
26
28
|
end
|
27
29
|
|
28
|
-
should
|
30
|
+
should "return correct endpoints" do
|
29
31
|
config = Fakturoid::Config.new do |c|
|
30
|
-
c.email =
|
31
|
-
c.api_key =
|
32
|
-
c.account =
|
32
|
+
c.email = "test@email.cz"
|
33
|
+
c.api_key = "XXXXXXXXXXX"
|
34
|
+
c.account = "testaccount"
|
33
35
|
end
|
34
36
|
|
35
|
-
assert_equal
|
36
|
-
assert_equal
|
37
|
+
assert_equal "https://app.fakturoid.cz/api/v2/accounts/testaccount", config.endpoint
|
38
|
+
assert_equal "https://app.fakturoid.cz/api/v2", config.endpoint_without_account
|
37
39
|
end
|
38
40
|
end
|
data/test/request_test.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
2
4
|
|
3
5
|
class Fakturoid::RequestTest < Fakturoid::TestCase
|
4
|
-
should
|
5
|
-
pdf = load_fixture(
|
6
|
+
should "should return pdf" do
|
7
|
+
pdf = load_fixture("invoice.pdf")
|
6
8
|
test_connection = Faraday.new do |builder|
|
7
9
|
builder.adapter :test do |stub|
|
8
|
-
stub.get(
|
10
|
+
stub.get("invoices/5/download.pdf") { |_env| [200, { content_type: "application/pdf" }, pdf] }
|
9
11
|
end
|
10
|
-
builder.headers = { content_type:
|
12
|
+
builder.headers = { content_type: "application/pdf" }
|
11
13
|
end
|
12
14
|
Fakturoid::Request.any_instance.stubs(:connection).returns(test_connection)
|
13
15
|
|
14
|
-
response = Fakturoid::Request.new(:get,
|
16
|
+
response = Fakturoid::Request.new(:get, "invoices/5/download.pdf", Fakturoid::Client::Invoice).call
|
15
17
|
assert !response.json?
|
16
18
|
assert_raises(NoMethodError) { response.name }
|
17
19
|
end
|