creditario-client 0.0.1.alpha

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.
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