freeagentrb 0.1.0 → 0.1.1

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: b570455fe0bf3cdc90330ad013a8f878f3c48405116d2033932ebc2db86bbb0f
4
- data.tar.gz: ca6b9f1bc67606328cddabfb1261beb77ec482c054214f58f0635041119c164e
3
+ metadata.gz: f8595ccfc827174d460c8aa3fe331018a409fc931f03cbc52d030a272af2b784
4
+ data.tar.gz: b5b2faca0fcad6bdd9975f5087ecae66fb5e5317b396b7920267ddbc0b6280d1
5
5
  SHA512:
6
- metadata.gz: 8d6349663051511f41b43b2312e01529549a13c5a36bbee06855ce3e1f10abe6c9eaff4002e847f1e3b706d9164bc7ba85278e23f82ac0d7ece82d4c81d858b6
7
- data.tar.gz: b03dd9e7852da63914f12ad3a6b0e93ebd22d2dff80f865b8810739ecc4cb6df2900cb4e8a0ae7e6563f9ac7a2c93fc7c140e6ae2622f4eee5db867492a0521f
6
+ metadata.gz: 43b7f6005955e663027d132d64e372a5757f90b66130f07c89766b55a47faea4d6932e2d2ce63d558049974aecefd221a11adf3763a46dd4e50769b93d848b10
7
+ data.tar.gz: cb5c620d30116b17f889ceeef7bafb84c09a0689a0b837711f88859245ddd49f9174fe3182ec6f8b2e2a8e1593df0caf4955217a5777bbbfcfc6aaa1f1327de3
data/.rubocop.yml ADDED
@@ -0,0 +1,11 @@
1
+ # Omakase Ruby styling for Rails
2
+ inherit_gem: { rubocop-rails-omakase: rubocop.yml }
3
+
4
+ # Overwrite or add rules to create your own house style
5
+ #
6
+ # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
7
+ # Layout/SpaceInsideArrayLiteralBrackets:
8
+ # Enabled: false
9
+
10
+ Rails/RefuteMethods:
11
+ Enabled: false
data/Gemfile CHANGED
@@ -6,4 +6,7 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
- gem "dotenv"
9
+ gem "dotenv"
10
+ gem "minitest", "~> 5.0"
11
+ gem "vcr"
12
+ gem "rubocop-rails-omakase", require: false
data/Gemfile.lock CHANGED
@@ -1,43 +1,98 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- freeagentrb (0.1.0)
5
- faraday (~> 1.7)
4
+ freeagentrb (0.1.1)
5
+ faraday (~> 2.11)
6
6
  faraday-multipart (~> 1.0)
7
- faraday_middleware (~> 1.1)
8
7
 
9
8
  GEM
10
9
  remote: https://rubygems.org/
11
10
  specs:
12
- dotenv (2.7.6)
13
- faraday (1.9.3)
14
- faraday-em_http (~> 1.0)
15
- faraday-em_synchrony (~> 1.0)
16
- faraday-excon (~> 1.1)
17
- faraday-httpclient (~> 1.0)
18
- faraday-multipart (~> 1.0)
19
- faraday-net_http (~> 1.0)
20
- faraday-net_http_persistent (~> 1.0)
21
- faraday-patron (~> 1.0)
22
- faraday-rack (~> 1.0)
23
- faraday-retry (~> 1.0)
24
- ruby2_keywords (>= 0.0.4)
25
- faraday-em_http (1.0.0)
26
- faraday-em_synchrony (1.0.0)
27
- faraday-excon (1.1.0)
28
- faraday-httpclient (1.0.1)
29
- faraday-multipart (1.0.3)
30
- multipart-post (>= 1.2, < 3)
31
- faraday-net_http (1.0.1)
32
- faraday-net_http_persistent (1.2.0)
33
- faraday-patron (1.0.0)
34
- faraday-rack (1.0.0)
35
- faraday-retry (1.0.3)
36
- faraday_middleware (1.2.0)
37
- faraday (~> 1.0)
38
- multipart-post (2.1.1)
39
- rake (13.0.6)
40
- ruby2_keywords (0.0.5)
11
+ activesupport (8.0.1)
12
+ base64
13
+ benchmark (>= 0.3)
14
+ bigdecimal
15
+ concurrent-ruby (~> 1.0, >= 1.3.1)
16
+ connection_pool (>= 2.2.5)
17
+ drb
18
+ i18n (>= 1.6, < 2)
19
+ logger (>= 1.4.2)
20
+ minitest (>= 5.1)
21
+ securerandom (>= 0.3)
22
+ tzinfo (~> 2.0, >= 2.0.5)
23
+ uri (>= 0.13.1)
24
+ ast (2.4.2)
25
+ base64 (0.2.0)
26
+ benchmark (0.4.0)
27
+ bigdecimal (3.1.9)
28
+ concurrent-ruby (1.3.5)
29
+ connection_pool (2.5.0)
30
+ dotenv (3.1.7)
31
+ drb (2.2.1)
32
+ faraday (2.12.2)
33
+ faraday-net_http (>= 2.0, < 3.5)
34
+ json
35
+ logger
36
+ faraday-multipart (1.1.0)
37
+ multipart-post (~> 2.0)
38
+ faraday-net_http (3.4.0)
39
+ net-http (>= 0.5.0)
40
+ i18n (1.14.7)
41
+ concurrent-ruby (~> 1.0)
42
+ json (2.9.1)
43
+ language_server-protocol (3.17.0.4)
44
+ logger (1.6.5)
45
+ minitest (5.25.4)
46
+ multipart-post (2.4.1)
47
+ net-http (0.6.0)
48
+ uri
49
+ parallel (1.26.3)
50
+ parser (3.3.7.0)
51
+ ast (~> 2.4.1)
52
+ racc
53
+ racc (1.8.1)
54
+ rack (3.1.8)
55
+ rainbow (3.1.1)
56
+ rake (13.2.1)
57
+ regexp_parser (2.10.0)
58
+ rubocop (1.71.0)
59
+ json (~> 2.3)
60
+ language_server-protocol (>= 3.17.0)
61
+ parallel (~> 1.10)
62
+ parser (>= 3.3.0.2)
63
+ rainbow (>= 2.2.2, < 4.0)
64
+ regexp_parser (>= 2.9.3, < 3.0)
65
+ rubocop-ast (>= 1.36.2, < 2.0)
66
+ ruby-progressbar (~> 1.7)
67
+ unicode-display_width (>= 2.4.0, < 4.0)
68
+ rubocop-ast (1.38.0)
69
+ parser (>= 3.3.1.0)
70
+ rubocop-minitest (0.36.0)
71
+ rubocop (>= 1.61, < 2.0)
72
+ rubocop-ast (>= 1.31.1, < 2.0)
73
+ rubocop-performance (1.23.1)
74
+ rubocop (>= 1.48.1, < 2.0)
75
+ rubocop-ast (>= 1.31.1, < 2.0)
76
+ rubocop-rails (2.29.1)
77
+ activesupport (>= 4.2.0)
78
+ rack (>= 1.1)
79
+ rubocop (>= 1.52.0, < 2.0)
80
+ rubocop-ast (>= 1.31.1, < 2.0)
81
+ rubocop-rails-omakase (1.0.0)
82
+ rubocop
83
+ rubocop-minitest
84
+ rubocop-performance
85
+ rubocop-rails
86
+ ruby-progressbar (1.13.0)
87
+ securerandom (0.4.1)
88
+ tzinfo (2.0.6)
89
+ concurrent-ruby (~> 1.0)
90
+ unicode-display_width (3.1.4)
91
+ unicode-emoji (~> 4.0, >= 4.0.4)
92
+ unicode-emoji (4.0.4)
93
+ uri (1.0.2)
94
+ vcr (6.3.1)
95
+ base64
41
96
 
42
97
  PLATFORMS
43
98
  x86_64-linux
@@ -45,7 +100,10 @@ PLATFORMS
45
100
  DEPENDENCIES
46
101
  dotenv
47
102
  freeagentrb!
103
+ minitest (~> 5.0)
48
104
  rake (~> 13.0)
105
+ rubocop-rails-omakase
106
+ vcr
49
107
 
50
108
  BUNDLED WITH
51
- 2.2.33
109
+ 2.6.3
data/Rakefile CHANGED
@@ -1,4 +1,10 @@
1
- # frozen_string_literal: true
2
-
3
1
  require "bundler/gem_tasks"
4
- task default: %i[]
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task default: :test
data/freeagentrb.gemspec CHANGED
@@ -5,17 +5,17 @@ require_relative "lib/free_agent/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "freeagentrb"
7
7
  spec.version = FreeAgent::VERSION
8
- spec.authors = ["Dean Perry"]
9
- spec.email = ["dean@deanpcmad.com"]
8
+ spec.authors = [ "Dean Perry" ]
9
+ spec.email = [ "dean@deanpcmad.com" ]
10
10
 
11
- spec.summary = "A Ruby library for interacting with the FreeAgent v2 API"
11
+ spec.summary = "Ruby library for the FreeAgent v2 API"
12
12
  spec.homepage = "https://deanpcmad.com"
13
+
13
14
  spec.license = "MIT"
14
15
  spec.required_ruby_version = ">= 2.6.0"
15
16
 
16
17
  spec.metadata["homepage_uri"] = spec.homepage
17
- # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
18
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
18
+ spec.metadata["source_code_uri"] = "https://github.com/deanpcmad/freeagentrb"
19
19
 
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -24,11 +24,8 @@ Gem::Specification.new do |spec|
24
24
  (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
25
25
  end
26
26
  end
27
- spec.bindir = "exe"
28
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
- spec.require_paths = ["lib"]
27
+ spec.require_paths = [ "lib" ]
30
28
 
31
- spec.add_dependency "faraday", "~> 1.7"
32
- spec.add_dependency "faraday_middleware", "~> 1.1"
29
+ spec.add_dependency "faraday", "~> 2.11"
33
30
  spec.add_dependency "faraday-multipart", "~> 1.0"
34
31
  end
@@ -25,7 +25,7 @@ module FreeAgent
25
25
  def bank_accounts
26
26
  BankAccountsResource.new(self)
27
27
  end
28
-
28
+
29
29
  def bank_transactions
30
30
  BankTransactionsResource.new(self)
31
31
  end
@@ -74,14 +74,20 @@ module FreeAgent
74
74
  BillsResource.new(self)
75
75
  end
76
76
 
77
+ def categories
78
+ CategoriesResource.new(self)
79
+ end
80
+
77
81
  def connection
78
82
  url = (sandbox == true ? SANDBOX_BASE_URL : BASE_URL)
79
83
  @connection ||= Faraday.new(url) do |conn|
80
84
  conn.request :authorization, :Bearer, access_token
81
85
  conn.request :json
86
+ conn.response :json
82
87
 
83
- conn.response :dates
84
- conn.response :json, content_type: "application/json"
88
+ conn.headers = {
89
+ "User-Agent" => "freeagentrb/v#{VERSION} (github.com/deanpcmad/freeagentrb)"
90
+ }
85
91
 
86
92
  conn.adapter adapter, @stubs
87
93
  end
@@ -95,6 +101,5 @@ module FreeAgent
95
101
  conn.request :multipart
96
102
  end
97
103
  end
98
-
99
104
  end
100
105
  end
@@ -1,27 +1,46 @@
1
1
  module FreeAgent
2
2
  class Collection
3
- attr_reader :data, :total
3
+ attr_reader :data, :total, :pagination
4
4
 
5
- def self.from_response(response, type:, key: nil)
5
+ def self.from_response(response, type:)
6
6
  body = response.body
7
7
 
8
- if key.is_a?(String)
9
- data = body[key].map { |attrs| type.new(attrs) }
10
- else
11
- data = body.map { |attrs| type.new(attrs) }
12
- end
8
+ data = body.values.first.map { |attrs| type.new(attrs) }
13
9
 
14
10
  total = response.headers["X-total-count"]
15
11
 
12
+ pagination = response.headers["Link"]&.split(", ")&.map do |link|
13
+ url, rel = link.match(/<(.+)>; rel='(.+)'/)&.captures
14
+ [ rel, url ]
15
+ end&.to_h
16
+
16
17
  new(
17
18
  data: data,
18
- total: total
19
+ total: total,
20
+ pagination: pagination
19
21
  )
20
22
  end
21
23
 
22
- def initialize(data:, total:)
24
+ def initialize(data:, total:, pagination: nil)
23
25
  @data = data
24
26
  @total = total
27
+ @pagination = pagination
28
+ end
29
+
30
+ def count
31
+ data.count
32
+ end
33
+
34
+ def each(&block)
35
+ data.each(&block)
36
+ end
37
+
38
+ def first
39
+ data.first
40
+ end
41
+
42
+ def last
43
+ data.last
25
44
  end
26
45
  end
27
46
  end
@@ -0,0 +1,128 @@
1
+ module FreeAgent
2
+ class ErrorGenerator < StandardError
3
+ attr_reader :http_status_code
4
+ attr_reader :freeagent_error_code
5
+ attr_reader :freeagent_error_message
6
+
7
+ def initialize(response_body, http_status_code)
8
+ @response_body = response_body
9
+ @http_status_code = http_status_code
10
+ set_freeagent_error_values
11
+ super(build_message)
12
+ end
13
+
14
+ private
15
+
16
+ def set_freeagent_error_values
17
+ @freeagent_error_code = @response_body.dig("error")
18
+ @freeagent_error_message = @response_body.dig("message")
19
+ end
20
+
21
+ def error_message
22
+ @freeagent_error_message || @response_body.dig("error")
23
+ rescue NoMethodError
24
+ "An unknown error occurred."
25
+ end
26
+
27
+ def build_message
28
+ if freeagent_error_code.nil?
29
+ return "Error #{@http_status_code}: #{error_message}"
30
+ end
31
+ "Error #{@http_status_code}: #{error_message} '#{freeagent_error_message}'"
32
+ end
33
+ end
34
+
35
+ module Errors
36
+ class BadRequestError < ErrorGenerator
37
+ private
38
+
39
+ def error_message
40
+ "Your request was malformed."
41
+ end
42
+ end
43
+
44
+ class AuthenticationMissingError < ErrorGenerator
45
+ private
46
+
47
+ def error_message
48
+ "You did not supply valid authentication credentials."
49
+ end
50
+ end
51
+
52
+ class ForbiddenError < ErrorGenerator
53
+ private
54
+
55
+ def error_message
56
+ "You are not allowed to perform that action."
57
+ end
58
+ end
59
+
60
+ class EntityNotFoundError < ErrorGenerator
61
+ private
62
+
63
+ def error_message
64
+ "No results were found for your request."
65
+ end
66
+ end
67
+
68
+ class ConflictError < ErrorGenerator
69
+ private
70
+
71
+ def error_message
72
+ "Your request was a conflict."
73
+ end
74
+ end
75
+
76
+ class TooManyRequestsError < ErrorGenerator
77
+ private
78
+
79
+ def error_message
80
+ "Your request exceeded the API rate limit."
81
+ end
82
+ end
83
+
84
+ class InternalError < ErrorGenerator
85
+ private
86
+
87
+ def error_message
88
+ "We were unable to perform the request due to server-side problems."
89
+ end
90
+ end
91
+
92
+ class ServiceUnavailableError < ErrorGenerator
93
+ private
94
+
95
+ def error_message
96
+ "You have been rate limited for sending more than 20 requests per second."
97
+ end
98
+ end
99
+
100
+ class NotImplementedError < ErrorGenerator
101
+ private
102
+
103
+ def error_message
104
+ "This resource has not been implemented."
105
+ end
106
+ end
107
+ end
108
+
109
+ class ErrorFactory
110
+ HTTP_ERROR_MAP = {
111
+ 400 => Errors::BadRequestError,
112
+ 401 => Errors::AuthenticationMissingError,
113
+ 403 => Errors::ForbiddenError,
114
+ 404 => Errors::EntityNotFoundError,
115
+ 409 => Errors::ConflictError,
116
+ 429 => Errors::TooManyRequestsError,
117
+ 500 => Errors::InternalError,
118
+ 503 => Errors::ServiceUnavailableError,
119
+ 501 => Errors::NotImplementedError
120
+ }.freeze
121
+
122
+ def self.create(response_body, http_status_code)
123
+ status = http_status_code
124
+ error_class = HTTP_ERROR_MAP[status] || ErrorGenerator
125
+ error_class.new(response_body, http_status_code) if error_class
126
+ end
127
+ end
128
+ end
@@ -5,7 +5,7 @@ module FreeAgent
5
5
  def initialize(attributes)
6
6
  super to_ostruct(attributes)
7
7
 
8
- # The FreeAgent API doesn't send an ID so generate it from the URL
8
+ # The FreeAgent API doesn't send an ID so generate it from the URL
9
9
  if attributes["url"]
10
10
  number = attributes["url"].match(/\d{2,}/)
11
11
  self.id = number[0] unless number.nil?
@@ -14,7 +14,7 @@ module FreeAgent
14
14
 
15
15
  def to_ostruct(obj)
16
16
  if obj.is_a?(Hash)
17
- OpenStruct.new(obj.map { |key, val| [key, to_ostruct(val)] }.to_h)
17
+ OpenStruct.new(obj.map { |key, val| [ key, to_ostruct(val) ] }.to_h)
18
18
  elsif obj.is_a?(Array)
19
19
  obj.map { |o| to_ostruct(o) }
20
20
  else # Assumed to be a primitive value
@@ -1,4 +1,21 @@
1
1
  module FreeAgent
2
2
  class BankTransaction < Object
3
+ def initialize(attributes)
4
+ super to_ostruct(attributes)
5
+
6
+ # Convert amounts to BigDecimal
7
+ self.amount = BigDecimal(self.amount.to_s).to_f if self.amount
8
+ self.unexplained_amount = BigDecimal(self.unexplained_amount.to_s).to_f if self.unexplained_amount
9
+
10
+ # Convert amounts in bank_transaction_explanations to BigDecimal
11
+ if self.bank_transaction_explanations
12
+ self.bank_transaction_explanations.each do |explanation|
13
+ explanation.id = explanation.url.match(/\d{2,}/)[0] if explanation.url
14
+ explanation.gross_value = BigDecimal(explanation.gross_value.to_s).to_f if explanation.gross_value
15
+ explanation.foreign_currency_value = BigDecimal(explanation.foreign_currency_value.to_s).to_f if explanation.foreign_currency_value
16
+ explanation.transfer_value = BigDecimal(explanation.transfer_value.to_s).to_f if explanation.transfer_value
17
+ end
18
+ end
19
+ end
3
20
  end
4
21
  end
@@ -0,0 +1,4 @@
1
+ module FreeAgent
2
+ class Category < Object
3
+ end
4
+ end
@@ -1,4 +1,13 @@
1
1
  module FreeAgent
2
2
  class Invoice < Object
3
+ def initialize(attributes)
4
+ super to_ostruct(attributes)
5
+
6
+ # Convert amounts to BigDecimal
7
+ self.net_value = BigDecimal(self.net_value.to_s).to_f if self.net_value
8
+ self.total_value = BigDecimal(self.total_value.to_s).to_f if self.total_value
9
+ self.paid_value = BigDecimal(self.paid_value.to_s).to_f if self.paid_value
10
+ self.due_value = BigDecimal(self.due_value.to_s).to_f if self.due_value
11
+ end
3
12
  end
4
13
  end
@@ -29,32 +29,20 @@ module FreeAgent
29
29
  end
30
30
 
31
31
  def handle_response(response)
32
- case response.status
33
- when 400
34
- raise Error, "Error 400: Your request was malformed. '#{response.body["errors"]["error"]["message"]}'"
35
- when 401
36
- raise Error, "Error 401: You did not supply valid authentication credentials. '#{response.body["errors"]["error"]["message"]}'"
37
- when 403
38
- raise Error, "Error 403: You are not allowed to perform that action. '#{response.body["errors"]["error"]["message"]}'"
39
- when 404
40
- raise Error, "Error 404: No results were found for your request. '#{response.body["errors"]["error"]["message"]}'"
41
- when 409
42
- raise Error, "Error 409: Your request was a conflict. '#{response.body["errors"]["error"]["message"]}'"
43
- when 422
44
- if response.body["errors"].is_a? Array
45
- raise Error, "Error 422: Unprocessable Entity. '#{response.body["errors"].map {|e| e['message']}.join(" & ")}'"
46
- else
47
- raise Error, "Error 422: Unprocessable Entity. '#{response.body["errors"]["error"]["message"]}'"
48
- end
49
- when 429
50
- raise Error, "Error 429: Your request exceeded the API rate limit. '#{response.body["errors"]["error"]["message"]}'"
51
- when 500
52
- raise Error, "Error 500: We were unable to perform the request due to server-side problems. '#{response.body["errors"]["error"]["message"]}'"
53
- when 503
54
- raise Error, "Error 503: You have been rate limited for sending more than 20 requests per second. '#{response.body["errors"]["error"]["message"]}'"
55
- end
56
-
57
- response
32
+ return true if response.status == 204
33
+ return response unless error?(response)
34
+
35
+ raise_error(response)
36
+ end
37
+
38
+ def error?(response)
39
+ [ 400, 401, 403, 404, 409, 429, 500, 501, 503 ].include?(response.status) ||
40
+ response.body&.key?("error")
41
+ end
42
+
43
+ def raise_error(response)
44
+ error = FreeAgent::ErrorFactory.create(response.body, response.status)
45
+ raise error if error
58
46
  end
59
47
  end
60
48
  end
@@ -1,6 +1,5 @@
1
1
  module FreeAgent
2
2
  class AttachmentsResource < Resource
3
-
4
3
  def retrieve(id:)
5
4
  response = get_request("attachments/#{id}")
6
5
  Attachment.new(response.body["attachment"])
@@ -10,6 +9,5 @@ module FreeAgent
10
9
  response = delete_request("attachments/#{id}")
11
10
  response.success?
12
11
  end
13
-
14
12
  end
15
13
  end
@@ -1,11 +1,10 @@
1
1
  module FreeAgent
2
2
  class BankAccountsResource < Resource
3
-
4
3
  def list(view: nil)
5
4
  url = view.nil? ? "bank_accounts" : "bank_accounts?view=#{view}"
6
5
 
7
6
  response = get_request(url)
8
- Collection.from_response(response, type: BankAccount, key: "bank_accounts")
7
+ Collection.from_response(response, type: BankAccount)
9
8
  end
10
9
 
11
10
  def retrieve(id:)
@@ -14,7 +13,7 @@ module FreeAgent
14
13
  end
15
14
 
16
15
  def create(type:, name:, opening_balance:, **params)
17
- attributes = {type: type, name: name, opening_balance: opening_balance}
16
+ attributes = { type: type, name: name, opening_balance: opening_balance }
18
17
  response = post_request("bank_accounts", body: attributes.merge(params))
19
18
  BankAccount.new(response.body["bank_account"]) if response.success?
20
19
  end
@@ -28,6 +27,5 @@ module FreeAgent
28
27
  response = delete_request("bank_accounts/#{id}")
29
28
  response.success?
30
29
  end
31
-
32
30
  end
33
31
  end
@@ -1,11 +1,10 @@
1
1
  module FreeAgent
2
2
  class BankTransactionExplanationsResource < Resource
3
-
4
3
  def list(bank_account:, **params)
5
- attributes = {bank_account: bank_account}
4
+ attributes = { bank_account: bank_account }
6
5
 
7
6
  response = get_request("bank_transaction_explanations", params: attributes.merge(params))
8
- Collection.from_response(response, type: BankTransactionExplanation, key: "bank_transaction_explanations")
7
+ Collection.from_response(response, type: BankTransactionExplanation)
9
8
  end
10
9
 
11
10
  def retrieve(id:)
@@ -13,17 +12,15 @@ module FreeAgent
13
12
  BankTransactionExplanation.new(response.body["bank_transaction_explanation"])
14
13
  end
15
14
 
16
- # Commented out as it needs more work
17
- # def create(**params)
18
- # raise "bank_account or bank_transaction is required" unless !params[:bank_account].nil? || !params[:bank_transaction].nil?
19
- # response = post_request("bank_transaction_explanations", body: params)
20
- # response.body
21
- # end
15
+ def create(**params)
16
+ raise "bank_account or bank_transaction is required" unless !params[:bank_account].nil? || !params[:bank_transaction].nil?
17
+ response = post_request("bank_transaction_explanations", body: params)
18
+ BankTransactionExplanation.new(response.body["bank_transaction_explanation"])
19
+ end
22
20
 
23
21
  def delete(id:)
24
22
  response = delete_request("bank_transaction_explanations/#{id}")
25
23
  response.success?
26
24
  end
27
-
28
25
  end
29
26
  end
@@ -1,11 +1,10 @@
1
1
  module FreeAgent
2
2
  class BankTransactionsResource < Resource
3
-
4
3
  def list(bank_account:, **params)
5
- attributes = {bank_account: bank_account}
4
+ attributes = { bank_account: bank_account }
6
5
 
7
6
  response = get_request("bank_transactions", params: attributes.merge(params))
8
- Collection.from_response(response, type: BankTransaction, key: "bank_transactions")
7
+ Collection.from_response(response, type: BankTransaction)
9
8
  end
10
9
 
11
10
  def retrieve(id:)
@@ -15,14 +14,14 @@ module FreeAgent
15
14
 
16
15
  # Statement should be an array of transactions
17
16
  def create(bank_account:, statement:)
18
- response = post_request("bank_transactions/statement?bank_account=#{bank_account}", body: {statement: statement})
17
+ response = post_request("bank_transactions/statement?bank_account=#{bank_account}", body: { statement: statement })
19
18
  response.success?
20
19
  end
21
20
 
22
21
  def upload(bank_account:, statement:)
23
22
  # This method uses Faraday Multipart (lostisland/faraday-multipart)
24
23
  payload = {}
25
- payload[:statement] = Faraday::Multipart::FilePart.new(statement, 'text/x-ruby')
24
+ payload[:statement] = Faraday::Multipart::FilePart.new(statement, "text/x-ruby")
26
25
 
27
26
  response = client.connection_upload.post "bank_transactions/statement?bank_account=#{bank_account}", payload
28
27
  response.success?
@@ -32,6 +31,5 @@ module FreeAgent
32
31
  response = delete_request("bank_transactions/#{id}")
33
32
  response.success?
34
33
  end
35
-
36
34
  end
37
35
  end
@@ -1,19 +1,18 @@
1
1
  module FreeAgent
2
2
  class BillsResource < Resource
3
-
4
3
  def list(**params)
5
4
  response = get_request("bills", params: params)
6
- Collection.from_response(response, type: Bill, key: "bills")
5
+ Collection.from_response(response, type: Bill)
7
6
  end
8
7
 
9
8
  def list_for_contact(contact:, **params)
10
9
  response = get_request("bills?contact=#{contact}", params: params)
11
- Collection.from_response(response, type: Bill, key: "bills")
10
+ Collection.from_response(response, type: Bill)
12
11
  end
13
12
 
14
13
  def list_for_project(project:, **params)
15
14
  response = get_request("bills?project=#{project}", params: params)
16
- Collection.from_response(response, type: Bill, key: "bills")
15
+ Collection.from_response(response, type: Bill)
17
16
  end
18
17
 
19
18
  def retrieve(id:)
@@ -22,14 +21,14 @@ module FreeAgent
22
21
  end
23
22
 
24
23
  def create(contact:, dated_on:, due_on:, reference:, bill_items:, **params)
25
- attributes = {contact: contact, dated_on: dated_on, due_on: due_on, reference: reference, bill_items: bill_items}
24
+ attributes = { contact: contact, dated_on: dated_on, due_on: due_on, reference: reference, bill_items: bill_items }
26
25
 
27
- response = post_request("bills", body: {bill: attributes.merge(params)})
26
+ response = post_request("bills", body: { bill: attributes.merge(params) })
28
27
  Bill.new(response.body["bill"]) if response.success?
29
28
  end
30
29
 
31
30
  def update(id:, **params)
32
- response = put_request("bills/#{id}", body: {bill: params})
31
+ response = put_request("bills/#{id}", body: { bill: params })
33
32
  Bill.new(response.body["bill"]) if response.success?
34
33
  end
35
34
 
@@ -37,6 +36,5 @@ module FreeAgent
37
36
  response = delete_request("bills/#{id}")
38
37
  response.success?
39
38
  end
40
-
41
39
  end
42
40
  end
@@ -0,0 +1,18 @@
1
+ module FreeAgent
2
+ class CategoriesResource < Resource
3
+ def list(**params)
4
+ response = get_request("categories", params: params)
5
+
6
+ responses = []
7
+
8
+ response.body.keys.each do |key|
9
+ response.body[key].each do |value|
10
+ value["category_type"] = key
11
+ responses << Category.new(value)
12
+ end
13
+ end
14
+
15
+ responses
16
+ end
17
+ end
18
+ end
@@ -1,10 +1,8 @@
1
1
  module FreeAgent
2
2
  class CompanyResource < Resource
3
-
4
3
  def retrieve
5
4
  response = get_request("company")
6
5
  Company.new(response.body["company"])
7
6
  end
8
-
9
7
  end
10
8
  end
@@ -1,9 +1,8 @@
1
1
  module FreeAgent
2
2
  class ContactsResource < Resource
3
-
4
3
  def list(**params)
5
4
  response = get_request("contacts", params: params)
6
- Collection.from_response(response, type: Contact, key: "contacts")
5
+ Collection.from_response(response, type: Contact)
7
6
  end
8
7
 
9
8
  def retrieve(id:)
@@ -27,6 +26,5 @@ module FreeAgent
27
26
  response = delete_request("contacts/#{id}")
28
27
  response.success?
29
28
  end
30
-
31
29
  end
32
30
  end
@@ -1,19 +1,18 @@
1
1
  module FreeAgent
2
2
  class CreditNotesResource < Resource
3
-
4
3
  def list(**params)
5
4
  response = get_request("credit_notes", params: params)
6
- Collection.from_response(response, type: CreditNote, key: "credit_notes")
5
+ Collection.from_response(response, type: CreditNote)
7
6
  end
8
7
 
9
8
  def list_for_contact(contact:, **params)
10
9
  response = get_request("credit_notes?contact=#{contact}", params: params)
11
- Collection.from_response(response, type: CreditNote, key: "credit_notes")
10
+ Collection.from_response(response, type: CreditNote)
12
11
  end
13
12
 
14
13
  def list_for_project(project:, **params)
15
14
  response = get_request("credit_notes?project=#{project}", params: params)
16
- Collection.from_response(response, type: CreditNote, key: "credit_notes")
15
+ Collection.from_response(response, type: CreditNote)
17
16
  end
18
17
 
19
18
  def retrieve(id:)
@@ -28,9 +27,9 @@ module FreeAgent
28
27
  end
29
28
 
30
29
  def create(contact:, dated_on:, payment_terms_in_days: 0, **params)
31
- attributes = {contact: contact, dated_on: dated_on, payment_terms_in_days: payment_terms_in_days}
30
+ attributes = { contact: contact, dated_on: dated_on, payment_terms_in_days: payment_terms_in_days }
32
31
 
33
- response = post_request("credit_notes", body: {credit_note: attributes.merge(params)})
32
+ response = post_request("credit_notes", body: { credit_note: attributes.merge(params) })
34
33
  CreditNote.new(response.body["credit_note"]) if response.success?
35
34
  end
36
35
 
@@ -40,7 +39,7 @@ module FreeAgent
40
39
  # end
41
40
 
42
41
  def update(id:, **params)
43
- response = put_request("credit_notes/#{id}", body: {credit_note: params})
42
+ response = put_request("credit_notes/#{id}", body: { credit_note: params })
44
43
  CreditNote.new(response.body["credit_note"]) if response.success?
45
44
  end
46
45
 
@@ -50,8 +49,8 @@ module FreeAgent
50
49
  end
51
50
 
52
51
  def email(id:, to:, **params)
53
- attributes = {to: to}
54
- response = post_request("credit_notes/#{id}/send_email", body: {credit_note: {email: attributes.merge(params)}})
52
+ attributes = { to: to }
53
+ response = post_request("credit_notes/#{id}/send_email", body: { credit_note: { email: attributes.merge(params) } })
55
54
  response.success?
56
55
  end
57
56
 
@@ -69,6 +68,5 @@ module FreeAgent
69
68
  response = put_request("credit_notes/#{id}/transitions/mark_as_cancelled", body: {})
70
69
  response.success?
71
70
  end
72
-
73
71
  end
74
72
  end
@@ -1,8 +1,7 @@
1
1
  module FreeAgent
2
2
  class EstimateItemsResource < Resource
3
-
4
3
  def create(estimate:, **params)
5
- attributes = {estimate: estimate}
4
+ attributes = { estimate: estimate }
6
5
 
7
6
  response = post_request("estimate_items", body: attributes.merge(params))
8
7
  EstimateItem.new(response.body["estimate_item"]) if response.success?
@@ -17,6 +16,5 @@ module FreeAgent
17
16
  response = delete_request("estimate_items/#{id}")
18
17
  response.success?
19
18
  end
20
-
21
19
  end
22
20
  end
@@ -1,24 +1,23 @@
1
1
  module FreeAgent
2
2
  class EstimatesResource < Resource
3
-
4
3
  def list(**params)
5
4
  response = get_request("estimates", params: params)
6
- Collection.from_response(response, type: Estimate, key: "estimates")
5
+ Collection.from_response(response, type: Estimate)
7
6
  end
8
7
 
9
8
  def list_for_contact(contact:, **params)
10
9
  response = get_request("estimates?contact=#{contact}", params: params)
11
- Collection.from_response(response, type: Estimate, key: "estimates")
10
+ Collection.from_response(response, type: Estimate)
12
11
  end
13
12
 
14
13
  def list_for_project(project:, **params)
15
14
  response = get_request("estimates?project=#{project}", params: params)
16
- Collection.from_response(response, type: Estimate, key: "estimates")
15
+ Collection.from_response(response, type: Estimate)
17
16
  end
18
17
 
19
18
  def list_for_invoice(invoice:, **params)
20
19
  response = get_request("estimates?invoice=#{invoice}", params: params)
21
- Collection.from_response(response, type: Estimate, key: "estimates")
20
+ Collection.from_response(response, type: Estimate)
22
21
  end
23
22
 
24
23
  def retrieve(id:)
@@ -33,9 +32,9 @@ module FreeAgent
33
32
  end
34
33
 
35
34
  def create(contact:, dated_on:, currency:, reference:, status: "Draft", estimate_type: "Estimate", **params)
36
- attributes = {contact: contact, dated_on: dated_on, status: status, estimate_type: estimate_type, currency: currency, reference: reference}
35
+ attributes = { contact: contact, dated_on: dated_on, status: status, estimate_type: estimate_type, currency: currency, reference: reference }
37
36
 
38
- response = post_request("estimates", body: {estimate: attributes.merge(params)})
37
+ response = post_request("estimates", body: { estimate: attributes.merge(params) })
39
38
  Estimate.new(response.body["estimate"]) if response.success?
40
39
  end
41
40
 
@@ -50,8 +49,8 @@ module FreeAgent
50
49
  end
51
50
 
52
51
  def email(id:, to:, **params)
53
- attributes = {to: to}
54
- response = post_request("estimates/#{id}/send_email", body: {estimate: {email: attributes.merge(params)}})
52
+ attributes = { to: to }
53
+ response = post_request("estimates/#{id}/send_email", body: { estimate: { email: attributes.merge(params) } })
55
54
  response.success?
56
55
  end
57
56
 
@@ -74,6 +73,5 @@ module FreeAgent
74
73
  response = put_request("estimates/#{id}/transitions/mark_as_rejected", body: {})
75
74
  response.success?
76
75
  end
77
-
78
76
  end
79
77
  end
@@ -1,19 +1,18 @@
1
1
  module FreeAgent
2
2
  class InvoicesResource < Resource
3
-
4
3
  def list(**params)
5
4
  response = get_request("invoices", params: params)
6
- Collection.from_response(response, type: Invoice, key: "invoices")
5
+ Collection.from_response(response, type: Invoice)
7
6
  end
8
7
 
9
8
  def list_for_contact(contact:, **params)
10
9
  response = get_request("invoices?contact=#{contact}", params: params)
11
- Collection.from_response(response, type: Invoice, key: "invoices")
10
+ Collection.from_response(response, type: Invoice)
12
11
  end
13
12
 
14
13
  def list_for_project(project:, **params)
15
14
  response = get_request("invoices?project=#{project}", params: params)
16
- Collection.from_response(response, type: Invoice, key: "invoices")
15
+ Collection.from_response(response, type: Invoice)
17
16
  end
18
17
 
19
18
  def retrieve(id:)
@@ -28,9 +27,9 @@ module FreeAgent
28
27
  end
29
28
 
30
29
  def create(contact:, dated_on:, payment_terms_in_days: 0, **params)
31
- attributes = {contact: contact, dated_on: dated_on, payment_terms_in_days: payment_terms_in_days}
30
+ attributes = { contact: contact, dated_on: dated_on, payment_terms_in_days: payment_terms_in_days }
32
31
 
33
- response = post_request("invoices", body: {invoice: attributes.merge(params)})
32
+ response = post_request("invoices", body: { invoice: attributes.merge(params) })
34
33
  Invoice.new(response.body["invoice"]) if response.success?
35
34
  end
36
35
 
@@ -40,7 +39,7 @@ module FreeAgent
40
39
  end
41
40
 
42
41
  def update(id:, **params)
43
- response = put_request("invoices/#{id}", body: {invoice: params})
42
+ response = put_request("invoices/#{id}", body: { invoice: params })
44
43
  Invoice.new(response.body["invoice"]) if response.success?
45
44
  end
46
45
 
@@ -50,8 +49,8 @@ module FreeAgent
50
49
  end
51
50
 
52
51
  def email(id:, to:, **params)
53
- attributes = {to: to}
54
- response = post_request("invoices/#{id}/send_email", body: {invoice: {email: attributes.merge(params)}})
52
+ attributes = { to: to }
53
+ response = post_request("invoices/#{id}/send_email", body: { invoice: { email: attributes.merge(params) } })
55
54
  response.success?
56
55
  end
57
56
 
@@ -84,6 +83,5 @@ module FreeAgent
84
83
  response = post_request("invoices/#{id}/direct_debit", body: {})
85
84
  response.success?
86
85
  end
87
-
88
86
  end
89
87
  end
@@ -1,14 +1,13 @@
1
1
  module FreeAgent
2
2
  class ProjectsResource < Resource
3
-
4
3
  def list(**params)
5
4
  response = get_request("projects", params: params)
6
- Collection.from_response(response, type: Project, key: "projects")
5
+ Collection.from_response(response, type: Project)
7
6
  end
8
7
 
9
8
  def list_for_contact(contact:, **params)
10
9
  response = get_request("projects?contact=#{contact}", params: params)
11
- Collection.from_response(response, type: Project, key: "projects")
10
+ Collection.from_response(response, type: Project)
12
11
  end
13
12
 
14
13
  def retrieve(id:)
@@ -17,7 +16,7 @@ module FreeAgent
17
16
  end
18
17
 
19
18
  def create(contact:, name:, status:, currency:, budget_units:, **params)
20
- attributes = {contact: contact, name: name, status: status, currency: currency, budget_units: budget_units}
19
+ attributes = { contact: contact, name: name, status: status, currency: currency, budget_units: budget_units }
21
20
 
22
21
  response = post_request("projects", body: attributes.merge(params))
23
22
  Project.new(response.body["project"]) if response.success?
@@ -32,6 +31,5 @@ module FreeAgent
32
31
  response = delete_request("projects/#{id}")
33
32
  response.success?
34
33
  end
35
-
36
34
  end
37
35
  end
@@ -1,14 +1,13 @@
1
1
  module FreeAgent
2
2
  class TasksResource < Resource
3
-
4
3
  def list(**params)
5
4
  response = get_request("tasks", params: params)
6
- Collection.from_response(response, type: Task, key: "tasks")
5
+ Collection.from_response(response, type: Task)
7
6
  end
8
7
 
9
8
  def list_for_project(project:, **params)
10
9
  response = get_request("tasks?project=#{project}", params: params)
11
- Collection.from_response(response, type: Task, key: "tasks")
10
+ Collection.from_response(response, type: Task)
12
11
  end
13
12
 
14
13
  def retrieve(id:)
@@ -17,7 +16,7 @@ module FreeAgent
17
16
  end
18
17
 
19
18
  def create(project:, name:, **params)
20
- attributes = {project: project, name: name}
19
+ attributes = { project: project, name: name }
21
20
 
22
21
  response = post_request("tasks", body: attributes.merge(params))
23
22
  Task.new(response.body["task"]) if response.success?
@@ -32,6 +31,5 @@ module FreeAgent
32
31
  response = delete_request("tasks/#{id}")
33
32
  response.success?
34
33
  end
35
-
36
34
  end
37
35
  end
@@ -1,24 +1,23 @@
1
1
  module FreeAgent
2
2
  class TimeslipsResource < Resource
3
-
4
3
  def list(**params)
5
4
  response = get_request("timeslips", params: params)
6
- Collection.from_response(response, type: Timeslip, key: "timeslips")
5
+ Collection.from_response(response, type: Timeslip)
7
6
  end
8
7
 
9
8
  def list_for_user(user:, **params)
10
9
  response = get_request("timeslips?user=#{user}", params: params)
11
- Collection.from_response(response, type: Timeslip, key: "timeslips")
10
+ Collection.from_response(response, type: Timeslip)
12
11
  end
13
12
 
14
13
  def list_for_task(task:, **params)
15
14
  response = get_request("timeslips?task=#{task}", params: params)
16
- Collection.from_response(response, type: Timeslip, key: "timeslips")
15
+ Collection.from_response(response, type: Timeslip)
17
16
  end
18
17
 
19
18
  def list_for_project(project:, **params)
20
19
  response = get_request("timeslips?project=#{project}", params: params)
21
- Collection.from_response(response, type: Timeslip, key: "timeslips")
20
+ Collection.from_response(response, type: Timeslip)
22
21
  end
23
22
 
24
23
  def retrieve(id:)
@@ -27,7 +26,7 @@ module FreeAgent
27
26
  end
28
27
 
29
28
  def create(task:, user:, project:, dated_on:, hours:, **params)
30
- attributes = {task: task, user: user, project: project, dated_on: dated_on, hours: hours}
29
+ attributes = { task: task, user: user, project: project, dated_on: dated_on, hours: hours }
31
30
 
32
31
  response = post_request("timeslips", body: attributes.merge(params))
33
32
  Timeslip.new(response.body["timeslip"]) if response.success?
@@ -42,6 +41,5 @@ module FreeAgent
42
41
  response = delete_request("timeslips/#{id}")
43
42
  response.success?
44
43
  end
45
-
46
44
  end
47
45
  end
@@ -1,6 +1,5 @@
1
1
  module FreeAgent
2
2
  class UsersResource < Resource
3
-
4
3
  def me
5
4
  response = get_request("users/me")
6
5
  User.new(response.body["user"])
@@ -8,7 +7,7 @@ module FreeAgent
8
7
 
9
8
  def list(**params)
10
9
  response = get_request("users", params: params)
11
- Collection.from_response(response, type: User, key: "users")
10
+ Collection.from_response(response, type: User)
12
11
  end
13
12
 
14
13
  def retrieve(id:)
@@ -17,7 +16,7 @@ module FreeAgent
17
16
  end
18
17
 
19
18
  def create(email:, first_name:, last_name:, role:, opening_mileage: 0, **params)
20
- attributes = {email: email, first_name: first_name, last_name: last_name, role: role, opening_mileage: opening_mileage}
19
+ attributes = { email: email, first_name: first_name, last_name: last_name, role: role, opening_mileage: opening_mileage }
21
20
 
22
21
  response = post_request("users", body: attributes.merge(params))
23
22
  User.new(response.body["user"]) if response.success?
@@ -29,7 +28,7 @@ module FreeAgent
29
28
  end
30
29
 
31
30
  def update_me(**params)
32
- response = put_request("users/me", body: {user: params})
31
+ response = put_request("users/me", body: { user: params })
33
32
  User.new(response.body["user"]) if response.success?
34
33
  end
35
34
 
@@ -37,6 +36,5 @@ module FreeAgent
37
36
  response = delete_request("users/#{id}")
38
37
  response.success?
39
38
  end
40
-
41
39
  end
42
40
  end
@@ -1,3 +1,3 @@
1
1
  module FreeAgent
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/free_agent.rb CHANGED
@@ -1,11 +1,14 @@
1
1
  require "faraday"
2
- require "faraday_middleware"
3
2
  require "faraday/multipart"
4
3
  require "json"
5
4
 
6
5
  require_relative "free_agent/version"
7
6
 
8
7
  module FreeAgent
8
+ autoload :Error, "free_agent/error"
9
+ autoload :Errors, "free_agent/error_generator"
10
+ autoload :ErrorGenerator, "free_agent/error_generator"
11
+ autoload :ErrorFactory, "free_agent/error_generator"
9
12
 
10
13
  autoload :Client, "free_agent/client"
11
14
  autoload :Collection, "free_agent/collection"
@@ -28,6 +31,7 @@ module FreeAgent
28
31
  autoload :EstimateItemsResource, "free_agent/resources/estimate_items"
29
32
  autoload :CreditNotesResource, "free_agent/resources/credit_notes"
30
33
  autoload :BillsResource, "free_agent/resources/bills"
34
+ autoload :CategoriesResource, "free_agent/resources/categories"
31
35
 
32
36
  autoload :Company, "free_agent/objects/company"
33
37
  autoload :Contact, "free_agent/objects/contact"
@@ -44,5 +48,5 @@ module FreeAgent
44
48
  autoload :EstimateItem, "free_agent/objects/estimate_item"
45
49
  autoload :CreditNote, "free_agent/objects/credit_note"
46
50
  autoload :Bill, "free_agent/objects/bill"
47
-
51
+ autoload :Category, "free_agent/objects/category"
48
52
  end
data/lib/freeagentrb.rb CHANGED
@@ -1 +1 @@
1
- require "free_agent"
1
+ require "free_agent"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freeagentrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dean Perry
8
- autorequire:
9
- bindir: exe
8
+ bindir: bin
10
9
  cert_chain: []
11
- date: 2022-01-09 00:00:00.000000000 Z
10
+ date: 2025-02-09 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -16,28 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '1.7'
18
+ version: '2.11'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: '1.7'
27
- - !ruby/object:Gem::Dependency
28
- name: faraday_middleware
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.1'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.1'
25
+ version: '2.11'
41
26
  - !ruby/object:Gem::Dependency
42
27
  name: faraday-multipart
43
28
  requirement: !ruby/object:Gem::Requirement
@@ -52,7 +37,6 @@ dependencies:
52
37
  - - "~>"
53
38
  - !ruby/object:Gem::Version
54
39
  version: '1.0'
55
- description:
56
40
  email:
57
41
  - dean@deanpcmad.com
58
42
  executables: []
@@ -60,6 +44,7 @@ extensions: []
60
44
  extra_rdoc_files: []
61
45
  files:
62
46
  - ".env.example"
47
+ - ".rubocop.yml"
63
48
  - Gemfile
64
49
  - Gemfile.lock
65
50
  - LICENSE.txt
@@ -72,12 +57,14 @@ files:
72
57
  - lib/free_agent/client.rb
73
58
  - lib/free_agent/collection.rb
74
59
  - lib/free_agent/error.rb
60
+ - lib/free_agent/error_generator.rb
75
61
  - lib/free_agent/object.rb
76
62
  - lib/free_agent/objects/attachment.rb
77
63
  - lib/free_agent/objects/bank_account.rb
78
64
  - lib/free_agent/objects/bank_transaction.rb
79
65
  - lib/free_agent/objects/bank_transaction_explanation.rb
80
66
  - lib/free_agent/objects/bill.rb
67
+ - lib/free_agent/objects/category.rb
81
68
  - lib/free_agent/objects/company.rb
82
69
  - lib/free_agent/objects/contact.rb
83
70
  - lib/free_agent/objects/credit_note.rb
@@ -94,6 +81,7 @@ files:
94
81
  - lib/free_agent/resources/bank_transaction_explanations.rb
95
82
  - lib/free_agent/resources/bank_transactions.rb
96
83
  - lib/free_agent/resources/bills.rb
84
+ - lib/free_agent/resources/categories.rb
97
85
  - lib/free_agent/resources/company.rb
98
86
  - lib/free_agent/resources/contacts.rb
99
87
  - lib/free_agent/resources/credit_notes.rb
@@ -111,7 +99,7 @@ licenses:
111
99
  - MIT
112
100
  metadata:
113
101
  homepage_uri: https://deanpcmad.com
114
- post_install_message:
102
+ source_code_uri: https://github.com/deanpcmad/freeagentrb
115
103
  rdoc_options: []
116
104
  require_paths:
117
105
  - lib
@@ -126,8 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
114
  - !ruby/object:Gem::Version
127
115
  version: '0'
128
116
  requirements: []
129
- rubygems_version: 3.1.6
130
- signing_key:
117
+ rubygems_version: 3.6.2
131
118
  specification_version: 4
132
- summary: A Ruby library for interacting with the FreeAgent v2 API
119
+ summary: Ruby library for the FreeAgent v2 API
133
120
  test_files: []