freeagentrb 0.1.0 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b570455fe0bf3cdc90330ad013a8f878f3c48405116d2033932ebc2db86bbb0f
4
- data.tar.gz: ca6b9f1bc67606328cddabfb1261beb77ec482c054214f58f0635041119c164e
3
+ metadata.gz: 88898202cc7b4ac0e04002a27eadce03209e346b6dfb923978957d5a3d2c5015
4
+ data.tar.gz: c09f7138b792427372c751aee5ab7b26150ed6788d3dc7017bd9d1e4c2401d78
5
5
  SHA512:
6
- metadata.gz: 8d6349663051511f41b43b2312e01529549a13c5a36bbee06855ce3e1f10abe6c9eaff4002e847f1e3b706d9164bc7ba85278e23f82ac0d7ece82d4c81d858b6
7
- data.tar.gz: b03dd9e7852da63914f12ad3a6b0e93ebd22d2dff80f865b8810739ecc4cb6df2900cb4e8a0ae7e6563f9ac7a2c93fc7c140e6ae2622f4eee5db867492a0521f
6
+ metadata.gz: 13a89e9d1296d6a4c92aa46b66a2fbd50b08fc603a6a5a3b5bfb5d5e00d82764018b52a07d8f8f9cb1982e33ace2af110ed7213cb59380e8072205994349a886
7
+ data.tar.gz: 25434579eaf40d09120e248aea740a947fff670ca08a7e72ab48f45888211034b1503956bf1335525234b133663180a44035d9030b88ac5dbe29b51fccd83c8e
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.2)
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,137 @@
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 UnprocessableContent < ErrorGenerator
77
+ private
78
+
79
+ def error_message
80
+ "Your request was unprocessable."
81
+ end
82
+ end
83
+
84
+ class TooManyRequestsError < ErrorGenerator
85
+ private
86
+
87
+ def error_message
88
+ "Your request exceeded the API rate limit."
89
+ end
90
+ end
91
+
92
+ class InternalError < ErrorGenerator
93
+ private
94
+
95
+ def error_message
96
+ "We were unable to perform the request due to server-side problems."
97
+ end
98
+ end
99
+
100
+ class ServiceUnavailableError < ErrorGenerator
101
+ private
102
+
103
+ def error_message
104
+ "You have been rate limited for sending more than 20 requests per second."
105
+ end
106
+ end
107
+
108
+ class NotImplementedError < ErrorGenerator
109
+ private
110
+
111
+ def error_message
112
+ "This resource has not been implemented."
113
+ end
114
+ end
115
+ end
116
+
117
+ class ErrorFactory
118
+ HTTP_ERROR_MAP = {
119
+ 400 => Errors::BadRequestError,
120
+ 401 => Errors::AuthenticationMissingError,
121
+ 403 => Errors::ForbiddenError,
122
+ 404 => Errors::EntityNotFoundError,
123
+ 409 => Errors::ConflictError,
124
+ 422 => Errors::UnprocessableContent,
125
+ 429 => Errors::TooManyRequestsError,
126
+ 500 => Errors::InternalError,
127
+ 503 => Errors::ServiceUnavailableError,
128
+ 501 => Errors::NotImplementedError
129
+ }.freeze
130
+
131
+ def self.create(response_body, http_status_code)
132
+ status = http_status_code
133
+ error_class = HTTP_ERROR_MAP[status] || ErrorGenerator
134
+ error_class.new(response_body, http_status_code) if error_class
135
+ end
136
+ end
137
+ 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, 422, 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.2"
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.2
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-13 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: []