emites-client 0.0.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.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +31 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +366 -0
  8. data/Rakefile +9 -0
  9. data/emites-client.gemspec +37 -0
  10. data/lib/emites.rb +44 -0
  11. data/lib/emites/client.rb +30 -0
  12. data/lib/emites/configuration.rb +12 -0
  13. data/lib/emites/entities/account.rb +8 -0
  14. data/lib/emites/entities/base.rb +9 -0
  15. data/lib/emites/entities/emitter.rb +31 -0
  16. data/lib/emites/entities/nfse.rb +29 -0
  17. data/lib/emites/entities/nfse_status.rb +15 -0
  18. data/lib/emites/entities/nfse_status_transition.rb +14 -0
  19. data/lib/emites/entities/nfse_values.rb +28 -0
  20. data/lib/emites/entities/rps.rb +9 -0
  21. data/lib/emites/entities/taker.rb +20 -0
  22. data/lib/emites/entities/taker_address.rb +21 -0
  23. data/lib/emites/entities/taker_contact.rb +9 -0
  24. data/lib/emites/entities/webhook.rb +9 -0
  25. data/lib/emites/exception.rb +11 -0
  26. data/lib/emites/http.rb +34 -0
  27. data/lib/emites/request.rb +53 -0
  28. data/lib/emites/resources/base.rb +45 -0
  29. data/lib/emites/resources/emitter.rb +98 -0
  30. data/lib/emites/resources/hooks.rb +25 -0
  31. data/lib/emites/resources/nfse.rb +173 -0
  32. data/lib/emites/resources/webhook.rb +84 -0
  33. data/lib/emites/response.rb +38 -0
  34. data/lib/emites/version.rb +3 -0
  35. data/spec/emites/client_spec.rb +45 -0
  36. data/spec/emites/configuration_spec.rb +13 -0
  37. data/spec/emites/entities/account_spec.rb +14 -0
  38. data/spec/emites/entities/base_spec.rb +28 -0
  39. data/spec/emites/entities/emitter_spec.rb +20 -0
  40. data/spec/emites/entities/nfse_spec.rb +148 -0
  41. data/spec/emites/entities/nfse_status_spec.rb +16 -0
  42. data/spec/emites/entities/nfse_status_transition_spec.rb +23 -0
  43. data/spec/emites/entities/nfse_values_spec.rb +19 -0
  44. data/spec/emites/entities/rps_spec.rb +15 -0
  45. data/spec/emites/entities/taker_address_spec.rb +18 -0
  46. data/spec/emites/entities/taker_contact_spec.rb +13 -0
  47. data/spec/emites/entities/taker_spec.rb +18 -0
  48. data/spec/emites/entities/webhook_spec.rb +14 -0
  49. data/spec/emites/exception_spec.rb +21 -0
  50. data/spec/emites/http_spec.rb +62 -0
  51. data/spec/emites/resources/base_spec.rb +96 -0
  52. data/spec/emites/resources/emitter_spec.rb +119 -0
  53. data/spec/emites/resources/nfse_spec.rb +214 -0
  54. data/spec/emites/resources/webhook_spec.rb +62 -0
  55. data/spec/emites_spec.rb +63 -0
  56. data/spec/fixtures/certificate.pfx +0 -0
  57. data/spec/shared_examples/bound_notifiers.rb +8 -0
  58. data/spec/shared_examples/entity_attributes.rb +9 -0
  59. data/spec/spec_helper.rb +38 -0
  60. data/spec/support/matchers/have_attr_accessor.rb +18 -0
  61. data/spec/vcr_cassettes/client/authenticated/false.yml +48 -0
  62. data/spec/vcr_cassettes/client/authenticated/true.yml +259 -0
  63. data/spec/vcr_cassettes/emitters/create/error.yml +57 -0
  64. data/spec/vcr_cassettes/emitters/create/success.yml +80 -0
  65. data/spec/vcr_cassettes/emitters/destroy/error.yml +47 -0
  66. data/spec/vcr_cassettes/emitters/destroy/success.yml +44 -0
  67. data/spec/vcr_cassettes/emitters/info/error.yml +47 -0
  68. data/spec/vcr_cassettes/emitters/info/success.yml +77 -0
  69. data/spec/vcr_cassettes/emitters/list/success.yml +135 -0
  70. data/spec/vcr_cassettes/emitters/partial_update/success.yml +90 -0
  71. data/spec/vcr_cassettes/emitters/search/returns_empty.yml +47 -0
  72. data/spec/vcr_cassettes/emitters/search/success.yml +76 -0
  73. data/spec/vcr_cassettes/nfse/cancel/success.yml +49 -0
  74. data/spec/vcr_cassettes/nfse/create/given_taker.yml +109 -0
  75. data/spec/vcr_cassettes/nfse/create/incomplete.yml +73 -0
  76. data/spec/vcr_cassettes/nfse/create/success.yml +112 -0
  77. data/spec/vcr_cassettes/nfse/create/without_taker.yml +73 -0
  78. data/spec/vcr_cassettes/nfse/destroy/success.yml +46 -0
  79. data/spec/vcr_cassettes/nfse/history/success.yml +83 -0
  80. data/spec/vcr_cassettes/nfse/info/success.yml +113 -0
  81. data/spec/vcr_cassettes/nfse/list/success.yml +1353 -0
  82. data/spec/vcr_cassettes/nfse/pdf/success.yml +48 -0
  83. data/spec/vcr_cassettes/nfse/status/success.yml +51 -0
  84. data/spec/vcr_cassettes/nfse/update/success.yml +113 -0
  85. data/spec/vcr_cassettes/nfse/xml/success.yml +48 -0
  86. data/spec/vcr_cassettes/webhooks/create/success.yml +53 -0
  87. data/spec/vcr_cassettes/webhooks/destroy/success.yml +46 -0
  88. data/spec/vcr_cassettes/webhooks/list/success.yml +53 -0
  89. data/spec/vcr_cassettes/webhooks/update/success.yml +52 -0
  90. metadata +390 -0
@@ -0,0 +1,45 @@
1
+ require "emites/resources/hooks"
2
+
3
+ module Emites
4
+ module Resources
5
+ class Base
6
+ include Wisper::Publisher
7
+ extend Hooks
8
+
9
+ attr_accessor :http
10
+
11
+ def initialize(http)
12
+ @http = http
13
+ end
14
+
15
+ def parsed_body(response)
16
+ MultiJson.load(response.body)
17
+ rescue MultiJson::ParseError
18
+ {}
19
+ end
20
+
21
+ protected
22
+
23
+ def respond_with_collection(response, naked_klass = entity_klass)
24
+ hash = parsed_body(response)
25
+ hash["collection"].map do |item|
26
+ naked_klass.new(item)
27
+ end
28
+ end
29
+
30
+ def respond_with_entity(response, naked_klass = entity_klass)
31
+ item = parsed_body(response)
32
+ naked_klass.new(item)
33
+ end
34
+
35
+ def base_klass
36
+ @base_klass ||= self.class.name.split("::").last
37
+ end
38
+
39
+ def entity_klass
40
+ @entity_klass ||= Emites::Entities.const_get(base_klass.to_sym)
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,98 @@
1
+ module Emites
2
+ module Resources
3
+
4
+ # A wrapper to Emites emitters API
5
+ #
6
+ # [API]
7
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/emitter.html
8
+ #
9
+ # @example Listing all emitters:
10
+ # client = Emites.client("MY_SECRET_TOKEN")
11
+ # client.emitters.list
12
+ #
13
+ # @example Creating an emitter:
14
+ # client = Emites.client("MY_SECRET_TOKEN")
15
+ # client.emitters.create({cnpj: "01001001000113", certificate: Base64.encode64(File.read("path/to/certificate.pfx"))})
16
+ #
17
+ # @see Emites.client
18
+ class Emitter < Base
19
+
20
+ # Creates an Emitter related to the Account
21
+ #
22
+ # [API]
23
+ # Method: <tt>POST /api/v1/emitters</tt>
24
+ #
25
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/emitter.html#criacao
26
+ #
27
+ # @param params [Hash] a hash with Emitter attributes
28
+ # @return [Emites::Entities::Emitter] the created Emitter
29
+ def create(params)
30
+ http.post("/emitters", { body: params }) do |response|
31
+ respond_with_entity(response)
32
+ end
33
+ end
34
+
35
+ # Retrieves an Emitter by it's id
36
+ #
37
+ # [API]
38
+ # Method: <tt>GET /api/v1/emitters/:id</tt>
39
+ #
40
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/emitter.html#detalhes
41
+ #
42
+ # @param id [Integer] the Emitter id
43
+ # @return [Emites::Entities::Emitter] the Emitter by it's id
44
+ def info(id)
45
+ http.get("/emitters/#{id}") do |response|
46
+ respond_with_entity(response)
47
+ end
48
+ end
49
+
50
+ # Lists all Emitters related to the account
51
+ #
52
+ # [API]
53
+ # Method: <tt>GET /api/v1/emitters</tt>
54
+ #
55
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/emitter.html#listagem
56
+ #
57
+ # @return [Array] an array of Emitter
58
+ def list
59
+ http.get("/emitters") do |response|
60
+ respond_with_collection(response)
61
+ end
62
+ end
63
+
64
+ # Lists all Emitters related to the account matching search results
65
+ #
66
+ # [API]
67
+ # Method: <tt>GET /api/v1/emitters?cnpj=:cnpj</tt>
68
+ #
69
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/emitter.html#filtros
70
+ #
71
+ # @param params [Hash] a hash with Emitter attributes
72
+ # @return [Array] an array of Emitter
73
+ def search(params)
74
+ http.get("/emitters", { params: params }) do |response|
75
+ respond_with_collection(response)
76
+ end
77
+ end
78
+
79
+ # Deletes an Emitter by it's id. Returns <tt>true</true> if deletion performed well, otherwise,
80
+ # returns <tt>false</tt>.
81
+ #
82
+ # [API]
83
+ # Method: <tt>DELETE /api/v1/emitters/:id</tt>
84
+ #
85
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/emitter.html#remocao
86
+ #
87
+ # @param id [Integer] the Emitter id
88
+ # @return [Boolean] whether deletion was performed or not
89
+ def destroy(id)
90
+ http.delete("/emitters/#{id}") do |response|
91
+ response.code == 204
92
+ end
93
+ end
94
+
95
+ notify :create, :destroy
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,25 @@
1
+ module Emites
2
+ module Resources
3
+ module Hooks
4
+
5
+ def notify(*hooked_methods)
6
+ apply_hooks(hooked_methods.flatten)
7
+ end
8
+
9
+ private
10
+
11
+ def apply_hooks(hooked_methods)
12
+ hooked_methods.each do |method|
13
+ alias_method "#{method}_without_notifier", method
14
+
15
+ define_method method do |*args|
16
+ result = send("#{method}_without_notifier", *args)
17
+ publish("emites.#{base_klass.downcase}.#{method}", result, args.flatten)
18
+ result
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,173 @@
1
+ module Emites
2
+ module Resources
3
+
4
+ # A wrapper to Emites NFSes API
5
+ #
6
+ # [API]
7
+ # Documentation: http://myfreecomm.github.io/emites/v1/modules/nfse.html
8
+ #
9
+ # @example Listing all NFSe:
10
+ # client = Emites.client("MY_SECRET_TOKEN")
11
+ # client.nfse.list
12
+ #
13
+ # @example Creating a NFSe:
14
+ # client = Emites.client("MY_SECRET_TOKEN")
15
+ # client.nfse.create({emitter_id: 1, serie: "a", ...)
16
+ #
17
+ # @see Emites.client
18
+ class Nfse < Base
19
+
20
+ # Lists all NFSes
21
+ #
22
+ # [API]
23
+ # Method: <tt>GET /api/v1/nfse</tt>
24
+ #
25
+ # Documentation: http://myfreecomm.github.io/emites/v1/modules/nfse.html#listagem
26
+ #
27
+ # @return [Array] an array of Webhook
28
+ def list
29
+ http.get("/nfse") do |response|
30
+ respond_with_collection(response)
31
+ end
32
+ end
33
+
34
+ # Retrieves a Nfse by it's id
35
+ #
36
+ # [API]
37
+ # Method: <tt>GET /api/v1/nfse/:id</tt>
38
+ #
39
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#detalhes
40
+ #
41
+ # @param id [Integer] the Nfse id
42
+ # @return [Emites::Entities::Nfse] the Nfse by it's id
43
+ def info(id)
44
+ http.get("/nfse/#{id}") do |response|
45
+ respond_with_entity(response)
46
+ end
47
+ end
48
+
49
+ # Retrieves a Nfse status by it's id
50
+ #
51
+ # [API]
52
+ # Method: <tt>GET /api/v1/nfse/:id/status</tt>
53
+ #
54
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#status
55
+ #
56
+ # @param id [Integer] the Nfse id
57
+ # @return [Emites::Entities::NfseStatus] the NfseStatus by it's id
58
+ def status(id)
59
+ http.get("/nfse/#{id}/status") do |response|
60
+ respond_with_entity(response, Entities::NfseStatus)
61
+ end
62
+ end
63
+
64
+ # Retrieves the entire Nfse status history by it's id
65
+ #
66
+ # [API]
67
+ # Method: <tt>GET /api/v1/nfse/:id/history</tt>
68
+ #
69
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#historico
70
+ #
71
+ # @param id [Integer] the Nfse id
72
+ # @return [Array] an array of Emites::Entities::NfseStatusTransition
73
+ def history(id)
74
+ http.get("/nfse/#{id}/history") do |response|
75
+ respond_with_collection(response, Entities::NfseStatusTransition)
76
+ end
77
+ end
78
+
79
+ # Retrieves Nfse PDF url
80
+ #
81
+ # [API]
82
+ # Method: <tt>GET /api/v1/nfse/:id/pdf</tt>
83
+ #
84
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#pdf
85
+ #
86
+ # @param id [Integer] the Nfse id
87
+ # @return [String] the url to redirect or an empty string if an error occurred
88
+ def pdf(id)
89
+ http.get("/nfse/#{id}/pdf") do |response|
90
+ response.headers.fetch("Location") { "" }
91
+ end
92
+ end
93
+
94
+ # Retrieves Nfse XML url
95
+ #
96
+ # [API]
97
+ # Method: <tt>GET /api/v1/nfse/:id/xml</tt>
98
+ #
99
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#xml
100
+ #
101
+ # @param id [Integer] the Nfse id
102
+ # @return [String] the url to redirect or an empty string if an error occurred
103
+ def xml(id)
104
+ http.get("/nfse/#{id}/xml") do |response|
105
+ response.headers.fetch("Location") { "" }
106
+ end
107
+ end
108
+
109
+ # Cancels a Nfse by it's id
110
+ #
111
+ # [API]
112
+ # Method: <tt>POST /api/v1/nfse/:id/cancel</tt>
113
+ #
114
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#cancelamento
115
+ #
116
+ # @param id [Integer] the Nfse id
117
+ # @return [Emites::Entities::NfseStatus] the NfseStatus by it's id
118
+ def cancel(id)
119
+ http.post("/nfse/#{id}/cancel") do |response|
120
+ respond_with_entity(response, Entities::NfseStatus)
121
+ end
122
+ end
123
+
124
+ # Deletes a Nfse by it's id
125
+ #
126
+ # [API]
127
+ # Method: <tt>DELETE /api/v1/nfse/:id</tt>
128
+ #
129
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#remocao
130
+ #
131
+ # @param id [Integer] the Nfse id
132
+ # @return [Boolean] whether deletion was performed or not
133
+ def destroy(id)
134
+ http.delete("/nfse/#{id}") do |response|
135
+ response.code == 204
136
+ end
137
+ end
138
+
139
+ # Creates an Nfse
140
+ #
141
+ # [API]
142
+ # Method: <tt>POST /api/v1/nfse</tt>
143
+ #
144
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#criacao
145
+ #
146
+ # @param params [Hash] a hash with Nfse attributes
147
+ # @return [Emites::Entities::Nfse] the created Nfse
148
+ def create(params)
149
+ http.post("/nfse", { body: params }) do |response|
150
+ respond_with_entity(response)
151
+ end
152
+ end
153
+
154
+ # Updates an Nfse
155
+ #
156
+ # [API]
157
+ # Method: <tt>PUT /api/v1/:id</tt>
158
+ #
159
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/nfse.html#atualizacao-parcial-e-completa
160
+ #
161
+ # @param id [Integer] the Nfse id
162
+ # @param params [Hash] a hash with Nfse attributes
163
+ # @return [Emites::Entities::Nfse] the created Nfse
164
+ def update(id, params)
165
+ http.put("/nfse/#{id}", { body: params }) do |response|
166
+ respond_with_entity(response)
167
+ end
168
+ end
169
+
170
+ notify :create, :update, :cancel, :destroy
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,84 @@
1
+ module Emites
2
+ module Resources
3
+
4
+ # A wrapper to Emites webhooks API
5
+ #
6
+ # [API]
7
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/webhooks.html
8
+ #
9
+ # @example Listing all webhooks:
10
+ # client = Emites.client("MY_SECRET_TOKEN")
11
+ # client.webhooks.list
12
+ #
13
+ # @example Creating an webhook:
14
+ # client = Emites.client("MY_SECRET_TOKEN")
15
+ # client.webhooks.create({name: "My Fake Web Hook", url: "http://web.hook")
16
+ #
17
+ # @see Emites.client
18
+ class Webhook < Base
19
+
20
+ # Lists all Webhooks related to the account
21
+ #
22
+ # [API]
23
+ # Method: <tt>GET /api/v1/webhooks</tt>
24
+ #
25
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/webhooks.html#listagem
26
+ #
27
+ # @return [Array] an array of Webhook
28
+ def list
29
+ http.get("/webhooks") do |response|
30
+ respond_with_collection(response)
31
+ end
32
+ end
33
+
34
+ # Updates an Webhook identified by <tt>id</tt>
35
+ #
36
+ # [API]
37
+ # Method: <tt>PUT /api/v1/webhooks/:id</tt>
38
+ #
39
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/webhooks.html#atualizacao
40
+ #
41
+ # @param id [Integer] the webhook id
42
+ # @param params [Hash] a hash with new data
43
+ # @return [Array] an array of Webhook
44
+ def update(id, params)
45
+ http.put("/webhooks/#{id}", { body: params }) do |response|
46
+ respond_with_entity(response)
47
+ end
48
+ end
49
+
50
+ # Deletes an Webhook by it's id. Returns <tt>true</true> if deletion performed well, otherwise,
51
+ # returns <tt>false</tt>.
52
+ #
53
+ # [API]
54
+ # Method: <tt>DELETE /api/v1/webhooks/:id</tt>
55
+ #
56
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/webhooks.html#remocao
57
+ #
58
+ # @param id [Integer] the Wehook id
59
+ # @return [Boolean] whether deletion was performed or not
60
+ def destroy(id)
61
+ http.delete("/webhooks/#{id}") do |response|
62
+ response.code == 204
63
+ end
64
+ end
65
+
66
+ # Creates an Webhook
67
+ #
68
+ # [API]
69
+ # Method: <tt>POST /api/v1/webhooks</tt>
70
+ #
71
+ # Documentation: http://myfreecomm.github.io/emites/sandbox/v1/modules/webhooks.html#criacao
72
+ #
73
+ # @param params [Hash] a hash with Webhook attributes
74
+ # @return [Emites::Entities::Webhook] the created Webhook
75
+ def create(params)
76
+ http.post("/webhooks", { body: params }) do |response|
77
+ respond_with_entity(response)
78
+ end
79
+ end
80
+
81
+ notify :create, :destroy, :update
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,38 @@
1
+ require "emites/exception"
2
+
3
+ module Emites
4
+ RequestTimeout = Class.new(Exception)
5
+ RequestError = Class.new(Exception)
6
+
7
+ class Response < SimpleDelegator
8
+
9
+ def resolve!(&block)
10
+ if success? || redirected?
11
+ block_given? ? yield(self) : self
12
+ elsif timed_out?
13
+ timeout!
14
+ else
15
+ error!
16
+ end
17
+ end
18
+
19
+ def redirected?
20
+ response_code && response_code >= 300 && response_code < 400
21
+ end
22
+
23
+ private
24
+
25
+ def timeout!
26
+ raise RequestTimeout
27
+ end
28
+
29
+ def error!
30
+ raise RequestError.new(
31
+ code: code,
32
+ message: status_message,
33
+ body: (MultiJson.load(body) rescue {})
34
+ )
35
+ end
36
+
37
+ end
38
+ end