creditario-client 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +14 -0
  4. data/.gitlab-ci.yml +23 -0
  5. data/.rubocop.yml +155 -0
  6. data/.travis.yml +5 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Dockerfile +3 -0
  9. data/Gemfile +8 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +241 -0
  12. data/Rakefile +21 -0
  13. data/bin/console +15 -0
  14. data/bin/setup +8 -0
  15. data/creditario-client.gemspec +35 -0
  16. data/lib/creditario/api/create.rb +29 -0
  17. data/lib/creditario/api/delete.rb +25 -0
  18. data/lib/creditario/api/list.rb +27 -0
  19. data/lib/creditario/api/multipart.rb +29 -0
  20. data/lib/creditario/api/request.rb +101 -0
  21. data/lib/creditario/api/retrieve.rb +32 -0
  22. data/lib/creditario/api/update.rb +32 -0
  23. data/lib/creditario/client.rb +183 -0
  24. data/lib/creditario/client/railtie.rb +14 -0
  25. data/lib/creditario/client/version.rb +9 -0
  26. data/lib/creditario/exceptions.rb +121 -0
  27. data/lib/creditario/repositories/applications.rb +50 -0
  28. data/lib/creditario/repositories/attachments.rb +50 -0
  29. data/lib/creditario/repositories/catalogs.rb +59 -0
  30. data/lib/creditario/repositories/contracts.rb +29 -0
  31. data/lib/creditario/repositories/credit_estimates.rb +29 -0
  32. data/lib/creditario/repositories/credits.rb +35 -0
  33. data/lib/creditario/repositories/customers.rb +50 -0
  34. data/lib/creditario/repositories/expenses.rb +41 -0
  35. data/lib/creditario/repositories/incomes.rb +41 -0
  36. data/lib/creditario/repositories/payments.rb +34 -0
  37. data/lib/creditario/repositories/products.rb +38 -0
  38. data/lib/creditario/repositories/references.rb +41 -0
  39. data/lib/creditario/resources/application.rb +27 -0
  40. data/lib/creditario/resources/attachment.rb +19 -0
  41. data/lib/creditario/resources/catalog.rb +35 -0
  42. data/lib/creditario/resources/contract.rb +21 -0
  43. data/lib/creditario/resources/credit.rb +19 -0
  44. data/lib/creditario/resources/credit_estimate.rb +19 -0
  45. data/lib/creditario/resources/customer.rb +25 -0
  46. data/lib/creditario/resources/expense.rb +19 -0
  47. data/lib/creditario/resources/income.rb +19 -0
  48. data/lib/creditario/resources/payment.rb +21 -0
  49. data/lib/creditario/resources/product.rb +21 -0
  50. data/lib/creditario/resources/reference.rb +19 -0
  51. data/lib/creditario/resources/resource.rb +96 -0
  52. data/lib/creditario/utils/paginated_collection.rb +45 -0
  53. data/lib/creditario/utils/resources_collection.rb +35 -0
  54. data/lib/generators/creditario/USAGE +13 -0
  55. data/lib/generators/creditario/install_generator.rb +17 -0
  56. data/lib/generators/creditario/templates/creditario.yml +12 -0
  57. data/lib/generators/creditario/templates/initializer.rb +4 -0
  58. data/rakelib/fixture_api_response.rake +10 -0
  59. data/rakelib/fixture_api_response.rb +114 -0
  60. metadata +214 -0
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+ require "sdoc"
6
+ require "rdoc/task"
7
+
8
+ RDoc::Task.new do |rdoc|
9
+ rdoc.rdoc_dir = "doc/"
10
+ rdoc.options << "--format=sdoc"
11
+ rdoc.options << "--exclude=test"
12
+ rdoc.template = "rails"
13
+ end
14
+
15
+ Rake::TestTask.new(:test) do |t|
16
+ t.libs << "test"
17
+ t.libs << "lib"
18
+ t.test_files = FileList["test/**/*_test.rb"]
19
+ end
20
+
21
+ task default: :test
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "creditario/client"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+
5
+ lib = File.expand_path("../lib", __FILE__)
6
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
+ require "creditario/client/version"
8
+
9
+ Gem::Specification.new do |spec|
10
+ spec.name = "creditario-client"
11
+ spec.version = Creditario::Client::VERSION
12
+ spec.authors = ["michelada.io"]
13
+ spec.email = ["info@michelada.io"]
14
+
15
+ spec.summary = "Ruby Client for the creditar.io API"
16
+ spec.homepage = "https://www.creditar.io"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency "oj", "~> 3.0.0"
27
+ spec.add_dependency "multipart-post", "2.0.0"
28
+
29
+ spec.add_development_dependency "bundler", "~> 2.0.1"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ spec.add_development_dependency "minitest", "~> 5.0"
32
+ spec.add_development_dependency "sdoc", "~> 1.0"
33
+ spec.add_development_dependency "rubocop", "~> 0.57.2"
34
+ spec.add_development_dependency "webmock", "~> 3.4.2"
35
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Creditario # :nodoc:
4
+ module API
5
+ ###
6
+ # == Creditario::API::Create
7
+ #
8
+ # Modulo encargado de generar recursos nuevos en la API de creditar.io
9
+ module Create
10
+ ###
11
+ # Realiza una llamada POST al path del Repositorio que esta haciendo
12
+ # uso de este modulo.
13
+ #
14
+ # Si todo sale bien devuelve una instancia del Recurso específico que el
15
+ # Repositorio maneja.
16
+ # De lo contrario, regresa un Hash con los errores arrojados por el servidor de creditar.io
17
+ def create(**params)
18
+ response = API.request(:post, self.resource_path, params)
19
+
20
+ attributes = response.dig("data").first
21
+ links = response.dig("links")
22
+
23
+ self.resource_class.new(attributes, links)
24
+ rescue Creditario::Exceptions::UnprocessableEntityError => exception
25
+ exception.server_response
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Creditario # :nodoc:
4
+ module API
5
+ ###
6
+ # == Creditario::API::Delete
7
+ #
8
+ # Modulo encargado de eliminar recursos existentes en la API de creditar.io
9
+ module Delete
10
+ ###
11
+ # Realiza una llamada DELETE al path del Repositorio que este haciendo uso
12
+ # de este modulo.
13
+ #
14
+ # Si todo sale bien, la respuesta no tendrá contenido alguno y el código de estado HTTP será 204.
15
+ # De lo contrario, el código de estado HTTP será diferente a 204 y la respuesta tendrá los detalles
16
+ # del error.
17
+ def delete(id)
18
+ path = "#{self.resource_path}/#{id}"
19
+ API.request(:delete, path).code == "204"
20
+ rescue Creditario::Exceptions::ResourceNotFoundError => exception
21
+ exception.server_response
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Creditario # :nodoc:
4
+ module API
5
+ ###
6
+ # == Creditario::API::List
7
+ #
8
+ # Modulo encargado de obtener recursos paginados de la API de creditar.io
9
+ module List
10
+ ###
11
+ # Realiza una llamada GET al path del Repositorio que esta haciendo uso
12
+ # de este modulo.
13
+ #
14
+ # Devuelve una colección paginada o normal de los recursos que el
15
+ # Repositorio maneja.
16
+ def list(query_params = {})
17
+ response = API.request(:get, self.resource_path, query_params)
18
+
19
+ if response.has_key? "pagination"
20
+ PaginatedCollection.new(response, self.resource_class)
21
+ else
22
+ ResourcesCollection.new(response, self.resource_class)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Creditario # :nodoc:
4
+ module API
5
+ ###
6
+ # == Creditario::API:Multipart
7
+ #
8
+ # Modulo encargado de generar recursos nuevos de tipo +multipart/form-data+ en la API de creditario.io
9
+ module Multipart
10
+ ###
11
+ # Realiza una llamada POST de tipo +multipart/form-data+ al path del Repositorio que esta haciendo
12
+ # uso de este modulo.
13
+ #
14
+ # Si todo sale bien devuelve una instancia del Recurso específico que el
15
+ # Repositorio maneja.
16
+ # De lo contrario, regresa un Hash con los errores arrojados por el servidor de creditar.io
17
+ def create(**params)
18
+ response = API.request(:multipart, self.resource_path, params)
19
+
20
+ attributes = response.dig("data").first
21
+ links = response.dig("links")
22
+
23
+ self.resource_class.new(attributes, links)
24
+ rescue Creditario::Exceptions::UnprocessableEntityError => exception
25
+ exception.server_response
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "net/http/post/multipart"
5
+
6
+ module Creditario # :nodoc:
7
+ module API # :nodoc:
8
+ ###
9
+ # Alias para el método Creditario::API::Request.request
10
+ def self.request(*params)
11
+ Request.request(*params)
12
+ end
13
+
14
+ ###
15
+ # == Creditario::API::Request
16
+ #
17
+ # Modulo encargado de ejecutar los requests HTTP de cualquier tipo
18
+ # a la API de creditar.io
19
+ module Request
20
+ class << self
21
+ ###
22
+ # Ejecuta un request HTTP a la API de creditar.io
23
+ #
24
+ # Los símbolos aceptados en el parámetro +method+ son:
25
+ #
26
+ # - :get
27
+ # - :post
28
+ # - :delete
29
+ # - :patch
30
+ # - :multipart
31
+ def request(method, path, params = {})
32
+ uri = URI(Creditario::Client.api_base + path)
33
+ request = request_from_method(method, uri, params)
34
+
35
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
36
+ http.request(request)
37
+ end
38
+
39
+ handle_errored_responses(response)
40
+
41
+ return response if response.body.nil?
42
+ Oj.load(response.body)
43
+ rescue Oj::ParseError => ex
44
+ raise Exceptions::InvalidResponseBodyError, ex.message
45
+ rescue Net::OpenTimeout => ex
46
+ raise Exceptions::APIBusyError, ex.message
47
+ rescue Errno::ECONNREFUSED => ex
48
+ raise Exceptions::APINotReachableError, ex.message
49
+ end
50
+
51
+ private
52
+
53
+ def request_from_method(method, uri, params)
54
+ case method
55
+ when :get
56
+ uri.query = URI.encode_www_form(params)
57
+ set_request_headers(Net::HTTP::Get.new(uri))
58
+ when :post
59
+ set_request_body(set_request_headers(Net::HTTP::Post.new(uri)), params)
60
+ when :multipart
61
+ set_authorization_headers(Net::HTTP::Post::Multipart.new(uri, params))
62
+ when :delete
63
+ set_request_headers(Net::HTTP::Delete.new(uri))
64
+ when :patch
65
+ set_request_body(set_request_headers(Net::HTTP::Patch.new(uri)), params)
66
+ end
67
+ end
68
+
69
+ def set_request_headers(request)
70
+ request = set_authorization_headers(request)
71
+
72
+ request["Accept"] = "application/vnd.creditar.v#{Creditario::Client.api_version}+json"
73
+ request["Content-Type"] = "application/json"
74
+
75
+ request
76
+ end
77
+
78
+ def set_authorization_headers(request)
79
+ raise Creditario::Exceptions::MissingAPIKeyError.new if Creditario::Client.api_key.nil?
80
+
81
+ request["Authorization"] = "Token token=#{Creditario::Client.api_key}"
82
+ request
83
+ end
84
+
85
+ def set_request_body(request, params)
86
+ request.body = params.to_json
87
+ request
88
+ end
89
+
90
+ def handle_errored_responses(response)
91
+ return if response.code.to_i < 400
92
+
93
+ raise Exceptions::InvalidAPIKeyError if response.code == "401"
94
+ raise Exceptions::ForbiddenError.new(response) if response.code == "403"
95
+ raise Exceptions::ResourceNotFoundError.new(response) if response.code == "404"
96
+ raise Exceptions::UnprocessableEntityError.new(response) if response.code == "422"
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Creditario # :nodoc:
4
+ module API
5
+ ###
6
+ # == Creditario::API::Retrieve
7
+ #
8
+ # Modulo encargado de obtener un solo recurso de la API de creditar.io
9
+ module Retrieve
10
+ ###
11
+ # Realiza una llamada GET al path del Repositorio que este haciendo uso
12
+ # de este modulo.
13
+ #
14
+ # Si todo sale bien devuelve una instancia del Recurso específico que el Repositorio maneja.
15
+ # De lo contrario, regresa un Hash con los errores arrojados por el servidor de creditar.io
16
+ def retrieve(id, query_params = {})
17
+ parts = [self.resource_path, id]
18
+ path = parts.compact.join("/")
19
+ response = API.request(:get, path, query_params)
20
+
21
+ attributes = response.dig("data").first
22
+ links = response.dig("links")
23
+
24
+ self.resource_class.new(attributes, links)
25
+ rescue Creditario::Exceptions::ResourceNotFoundError => exception
26
+ exception.server_response
27
+ rescue Creditario::Exceptions::UnprocessableEntityError => exception
28
+ exception.server_response
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Creditario # :nodoc:
4
+ module API
5
+ ###
6
+ # == Creditario::API::Update
7
+ #
8
+ # Modulo encargado de actualizar recursos existentes en la API de creditar.io
9
+ module Update
10
+ ###
11
+ # Realizar una llamada PATCH al path del Repositorio que esta haciendo uso
12
+ # de este modulo.
13
+ #
14
+ # Si todo sale bien devuelve una instancia del Recurso específico que el Repositorio maneja.
15
+ # De lo contrario, regresa un Hash con los errores arrojados por el servidor de creditar.io
16
+ def update(id, params = {}, include_param = nil)
17
+ path = "#{self.resource_path}/#{id}"
18
+ path = include_param.nil? ? path : path + "?include=#{include_param}"
19
+ response = API.request(:patch, path, params)
20
+
21
+ attributes = response.dig("data").first
22
+ links = response.dig("links")
23
+
24
+ self.resource_class.new(attributes, links)
25
+ rescue Creditario::Exceptions::UnprocessableEntityError,
26
+ Creditario::Exceptions::ResourceNotFoundError,
27
+ Creditario::Exceptions::ForbiddenError => exception
28
+ exception.server_response
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "oj"
4
+
5
+ require "creditario/client/version"
6
+ require "creditario/client/railtie" if defined?(Rails)
7
+
8
+ require "creditario/exceptions"
9
+
10
+ require "creditario/api/request"
11
+ require "creditario/api/create"
12
+ require "creditario/api/multipart"
13
+ require "creditario/api/delete"
14
+ require "creditario/api/list"
15
+ require "creditario/api/retrieve"
16
+ require "creditario/api/update"
17
+
18
+ require "creditario/utils/paginated_collection"
19
+ require "creditario/utils/resources_collection"
20
+
21
+ require "creditario/resources/resource"
22
+ require "creditario/resources/product"
23
+ require "creditario/resources/credit_estimate"
24
+ require "creditario/resources/contract"
25
+ require "creditario/resources/expense"
26
+ require "creditario/resources/income"
27
+ require "creditario/resources/reference"
28
+ require "creditario/resources/application"
29
+ require "creditario/resources/customer"
30
+ require "creditario/resources/catalog"
31
+ require "creditario/resources/attachment"
32
+ require "creditario/resources/credit"
33
+ require "creditario/resources/payment"
34
+
35
+ require "creditario/repositories/applications"
36
+ require "creditario/repositories/customers"
37
+ require "creditario/repositories/products"
38
+ require "creditario/repositories/credit_estimates"
39
+ require "creditario/repositories/contracts"
40
+ require "creditario/repositories/catalogs"
41
+ require "creditario/repositories/incomes"
42
+ require "creditario/repositories/expenses"
43
+ require "creditario/repositories/references"
44
+ require "creditario/repositories/attachments"
45
+ require "creditario/repositories/credits"
46
+ require "creditario/repositories/payments"
47
+
48
+ module Creditario # :nodoc:
49
+ ###
50
+ # == Creditario::Client
51
+ # Modulo que será utilizado para consumir la API de creditar.io
52
+ module Client
53
+ ###
54
+ # URL al ambiente de *production* de la API de creditar.io
55
+ @api_base = "https://www.creditar.io"
56
+
57
+ ###
58
+ # Version a utilizar de la API de creditar.io
59
+ @api_version = 1
60
+
61
+ class << self
62
+ ###
63
+ # La API Key es necesaria para cualquier interacción con la API de creditar.io
64
+ #
65
+ # Después de requerir la gema, lo más recomendado es definir la API Key a
66
+ # utilizar en todas las llamadas a la API.
67
+ #
68
+ # ==== Ejemplo
69
+ # Creditario::Client.api_key = "BMBE96Wva8NaYMmVx4RavpXSy6Y6HKFe"
70
+ attr_accessor :api_key
71
+
72
+ ###
73
+ # URL en la cual se ejecutarán las interacciones con la API de creditar.io
74
+ #
75
+ # Util cuando se desea utilizar el ambiente de *staging* por ejemplo.
76
+ #
77
+ # ==== Ejemplo
78
+ #
79
+ # Creditario::Client.api_base = "https://staging.creditar.io"
80
+ attr_accessor :api_base
81
+
82
+ ###
83
+ # Versión a utilizar de la API de creditar.io
84
+ # Por default es 1
85
+ attr_accessor :api_version
86
+
87
+ ###
88
+ # Método de acceso al repositorio de Productos.
89
+ #
90
+ # Para más información, puedes consultar la documentación de Creditario::Products
91
+ def products
92
+ Creditario::Products
93
+ end
94
+
95
+ ###
96
+ # Método de acceso al repositorio de Clientes.
97
+ #
98
+ # Para más información, puedes consultar la documentación de Creditario::Customers
99
+ def customers
100
+ Creditario::Customers
101
+ end
102
+
103
+ ###
104
+ # Método de acceso al repositorio de Solicitudes.
105
+ #
106
+ # Para más información, puedes consultar la documentación de Creditario::Applications
107
+ def applications
108
+ Creditario::Applications
109
+ end
110
+
111
+ ###
112
+ # Método de acesso al repositorio de Contratos.
113
+ #
114
+ # Para más información, puedes consultrar la documentación de Creditario::Contracts
115
+ def contracts
116
+ Creditario::Contracts
117
+ end
118
+
119
+ ###
120
+ # Método de acceso al repositorio de Catálogos.
121
+ #
122
+ # Para más información, puedes consultar la documentación de Creditario::Catalogs
123
+ def catalogs
124
+ Creditario::Catalogs
125
+ end
126
+
127
+ # Método de acceso al repositorio de Ingresos.
128
+ #
129
+ # Para más información, puedes consultar la documentación de Creditario::Incomes
130
+ def incomes
131
+ Creditario::Incomes
132
+ end
133
+
134
+ ###
135
+ # Método de acceso al repositorio de Egresos.
136
+ #
137
+ # Para más información, puedes consultar la documentación de Creditario::Expenses
138
+ def expenses
139
+ Creditario::Expenses
140
+ end
141
+
142
+ ###
143
+ # Método de acceso al repositorio de Referencias.
144
+ #
145
+ # Para más información, puedes consultar la documentación de Creditario::References
146
+ def references
147
+ Creditario::References
148
+ end
149
+
150
+ ###
151
+ # Método de acceso al repositorio de Archivos.
152
+ #
153
+ # Para más información, puede consultar la documentación de Creditario::Attachments
154
+ def attachments
155
+ Creditario::Attachments
156
+ end
157
+
158
+ ###
159
+ # Método de acceso al repositorio de Estimaciones de Crédito
160
+ #
161
+ # Para más información, puede consultar la documentación de Creditario::CreditEstimates
162
+ def credit_estimates
163
+ Creditario::CreditEstimates
164
+ end
165
+
166
+ ###
167
+ # Método de acceso al repositorio de Créditos
168
+ #
169
+ # Para más información, puede consultar la documentación de Creditario::Credits
170
+ def credits
171
+ Creditario::Credits
172
+ end
173
+
174
+ ###
175
+ # Método de acceso al repositorio de Pagos
176
+ #
177
+ # Para más información, puede consultar la documentación de Creditario::Payments
178
+ def payments
179
+ Creditario::Payments
180
+ end
181
+ end
182
+ end
183
+ end