emites-client 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require "rspec/core/rake_task"
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task default: :spec
7
+ rescue LoadError
8
+ # no rspec available
9
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require "emites/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "emites-client"
9
+ spec.version = Emites::VERSION
10
+ spec.authors = ["Leandro Thimóteo", "Rodrigo Tassinari", "Vagner Zampieri", "Wanderson Policarpo"]
11
+ spec.email = %w(leandro.thimoteo rodrigo.tassinari vagner.zampieri wanderson.policarpo).map { |nick| "#{nick}@myfreecomm.com.br" }
12
+ spec.summary = %q{Official Ruby client for the Emites API.}
13
+ spec.description = %q{Official Ruby client for the Emites API. Emites is a system for creating "notas fiscais eletrônicas" (NFe / NFSe) in Brazil.}
14
+ spec.homepage = "https://github.com/myfreecomm/emites-client-ruby"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "typhoeus", "~> 0.7"
23
+ spec.add_dependency "multi_json", "~> 1.9"
24
+ spec.add_dependency "virtus", "~> 1.0"
25
+ spec.add_dependency "wisper", "~> 1.6"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.7"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency 'rdoc', '~> 4.0'
30
+ spec.add_development_dependency "rspec", "~> 3.2"
31
+ spec.add_development_dependency "pry", "~> 0.10"
32
+ spec.add_development_dependency "pry-nav", "~> 0.2"
33
+ spec.add_development_dependency "awesome_print", "~> 1.1"
34
+ spec.add_development_dependency "simplecov", "~> 0.9"
35
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4"
36
+ spec.add_development_dependency "vcr", "~> 2.9"
37
+ end
data/lib/emites.rb ADDED
@@ -0,0 +1,44 @@
1
+ require "typhoeus"
2
+ require "multi_json"
3
+ require "wisper"
4
+
5
+ require "emites/version"
6
+ require "emites/configuration"
7
+ require "emites/http"
8
+ require "emites/client"
9
+
10
+ require "emites/entities/base"
11
+ require "emites/entities/account"
12
+ require "emites/entities/emitter"
13
+ require "emites/entities/taker_address"
14
+ require "emites/entities/taker_contact"
15
+ require "emites/entities/taker"
16
+ require "emites/entities/rps"
17
+ require "emites/entities/nfse_status"
18
+ require "emites/entities/nfse_status_transition"
19
+ require "emites/entities/nfse_values"
20
+ require "emites/entities/nfse"
21
+ require "emites/entities/webhook"
22
+
23
+ require "emites/resources/base"
24
+ require "emites/resources/emitter"
25
+ require "emites/resources/webhook"
26
+ require "emites/resources/nfse"
27
+
28
+ module Emites
29
+ def self.configuration
30
+ @configuration ||= Configuration.new
31
+ end
32
+
33
+ def self.configure
34
+ yield(configuration) if block_given?
35
+ end
36
+
37
+ def self.client(token)
38
+ Client.new(token)
39
+ end
40
+
41
+ def self.subscribe(event, callback)
42
+ Wisper.subscribe(callback, on: event, with: :call)
43
+ end
44
+ end
@@ -0,0 +1,30 @@
1
+ module Emites
2
+ class Client
3
+ attr_reader :http
4
+
5
+ def initialize(token)
6
+ @http = Http.new(token)
7
+ end
8
+
9
+ def authenticated?
10
+ http.get("") do |response|
11
+ response.code == 200
12
+ end
13
+ rescue RequestError => e
14
+ raise e unless e.code == 401
15
+ false
16
+ end
17
+
18
+ def emitters
19
+ Resources::Emitter.new(http)
20
+ end
21
+
22
+ def webhooks
23
+ Resources::Webhook.new(http)
24
+ end
25
+
26
+ def nfse
27
+ Resources::Nfse.new(http)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ require "base64"
2
+
3
+ module Emites
4
+ class Configuration
5
+ attr_accessor :url, :user_agent
6
+
7
+ def initialize
8
+ @url = "https://app.emites.com.br/api/v1"
9
+ @user_agent = "Emites Ruby Client v#{Emites::VERSION}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ module Emites
2
+ module Entities
3
+ class Account < Base
4
+ attribute :id, Integer
5
+ attribute :name, String
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ require "virtus"
2
+
3
+ module Emites
4
+ module Entities
5
+ class Base
6
+ include Virtus.model
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,31 @@
1
+ module Emites
2
+ module Entities
3
+ class Emitter < Base
4
+ attribute :id, Integer
5
+ attribute :email, String
6
+ attribute :social_reason, String
7
+ attribute :cnpj, String
8
+ attribute :fancy_name, String
9
+ attribute :state_inscription, String
10
+ attribute :city_inscription, String
11
+ attribute :state, String
12
+ attribute :city, String
13
+ attribute :neighborhood, String
14
+ attribute :street_type, String
15
+ attribute :street, String
16
+ attribute :number, String
17
+ attribute :zip_code, String
18
+ attribute :complement, String
19
+ attribute :phone, String
20
+ attribute :certificate, String
21
+ attribute :password, String
22
+ attribute :environment, String
23
+ attribute :filename, String
24
+ attribute :latest_serie, String
25
+ attribute :latest_number, Integer
26
+ attribute :code_tax_regime, Integer
27
+ attribute :national_simple_optant, Boolean
28
+ attribute :cultural_promoter, Boolean
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module Emites
2
+ module Entities
3
+ class Nfse < Base
4
+ attribute :id, Integer
5
+ attribute :emitter_id, Integer
6
+ attribute :taker, Taker
7
+ attribute :rps_situation, Integer
8
+ attribute :serie, String
9
+ attribute :number, Integer
10
+ attribute :rps_type, Integer
11
+ attribute :emission_date, DateTime
12
+ attribute :operation_nature, Integer
13
+ attribute :other_informations, String
14
+ attribute :competence, Date
15
+ attribute :special_regime, Integer
16
+ attribute :status, String
17
+ attribute :description, String
18
+ attribute :send_nfse_taker, Boolean
19
+ attribute :service_values, NfseValues
20
+ attribute :_links, Array
21
+
22
+ def url(action)
23
+ links = self._links || []
24
+ link = links.find { |link| link["rel"].to_s == action.to_s } || {}
25
+ link.fetch("href") { "" }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module Emites
2
+ module Entities
3
+ class NfseStatus < Base
4
+ attribute :id, Integer
5
+ attribute :status, String
6
+ attribute :description, String
7
+ attribute :nfse_key, String
8
+ attribute :nfse_number, String
9
+ attribute :number, Integer
10
+ attribute :mirror, String
11
+ attribute :xml, String
12
+ attribute :errors, Array
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module Emites
2
+ module Entities
3
+ class NfseStatusTransition < Base
4
+ attribute :id, Integer
5
+ attribute :token_description, String
6
+ attribute :from_status, String
7
+ attribute :to_status, String
8
+ attribute :date, DateTime
9
+ attribute :emitter, Emitter
10
+ attribute :rps, Rps
11
+ attribute :account, Account
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ module Emites
2
+ module Entities
3
+ class NfseValues < Base
4
+ attribute :id, Integer
5
+ attribute :service_amount, Decimal, precision: 16, scale: 2
6
+ attribute :calculation_base, Decimal, precision: 16, scale: 2
7
+ attribute :deduction_amount, Decimal, precision: 16, scale: 2
8
+ attribute :retained_iss, Boolean
9
+ attribute :iss_percentage, Decimal, precision: 16, scale: 2
10
+ attribute :iss_amount, Decimal, precision: 16, scale: 2
11
+ attribute :pis_amount, Decimal, precision: 16, scale: 2
12
+ attribute :cofins_amount, Decimal, precision: 16, scale: 2
13
+ attribute :inss_amount, Decimal, precision: 16, scale: 2
14
+ attribute :ir_amount, Decimal, precision: 16, scale: 2
15
+ attribute :csll_amount, Decimal, precision: 16, scale: 2
16
+ attribute :discount_conditioning_amount, Decimal, precision: 16, scale: 2
17
+ attribute :service_item_code, String
18
+ attribute :city_tax_code, String
19
+ attribute :cnae_code, Integer
20
+ attribute :description, String
21
+ attribute :city_code, Integer
22
+ attribute :nfse_liquid_amount, Decimal, precision: 16, scale: 2
23
+ attribute :other_retentions_amount, Decimal, precision: 16, scale: 2
24
+ attribute :retained_iss_amount, Decimal, precision: 16, scale: 2
25
+ attribute :unconditioned_discount_amount, Decimal, precision: 16, scale: 2
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ module Emites
2
+ module Entities
3
+ class Rps < Base
4
+ attribute :number, Integer
5
+ attribute :serie, String
6
+ attribute :rps_type, Integer
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ module Emites
2
+ module Entities
3
+ class Taker < Base
4
+ attribute :id, Integer
5
+ attribute :cpf, String
6
+ attribute :cnpj, String
7
+ attribute :city_inscription, String
8
+ attribute :social_reason, String
9
+ attribute :fancy_name, String
10
+ attribute :state_inscription, String
11
+ attribute :substitute_state_inscription, String
12
+ attribute :special_situation, Integer
13
+ attribute :foreign_taker, Boolean
14
+ attribute :allow_incomplete, Boolean
15
+ attribute :is_complete, Boolean
16
+ attribute :address, TakerAddress
17
+ attribute :contact, TakerContact
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module Emites
2
+ module Entities
3
+ class TakerAddress < Base
4
+ attribute :id, Integer
5
+ attribute :street, String
6
+ attribute :number, String
7
+ attribute :complement, String
8
+ attribute :neighborhood, String
9
+ attribute :city_code, Integer
10
+ attribute :state, String
11
+ attribute :zip_code, String
12
+ attribute :street_type, String
13
+ attribute :neighborhood_type, String
14
+ attribute :city, String
15
+ attribute :reference_point, String
16
+ attribute :country, String
17
+ attribute :country_code, Integer
18
+ attribute :country_abbreviation, String
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module Emites
2
+ module Entities
3
+ class TakerContact < Base
4
+ attribute :id, Integer
5
+ attribute :phone, String
6
+ attribute :email, String
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Emites
2
+ module Entities
3
+ class Webhook < Base
4
+ attribute :id, Integer
5
+ attribute :name, String
6
+ attribute :url, String
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Emites
2
+ class Exception < StandardError
3
+ attr_accessor :code, :body
4
+
5
+ def initialize(args = {})
6
+ super(args[:message])
7
+ @code = args[:code]
8
+ @body = args[:body]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ require "emites/request"
2
+ require "emites/response"
3
+
4
+ module Emites
5
+ class Http
6
+ attr_reader :token
7
+
8
+ def initialize(token)
9
+ @token = token
10
+ end
11
+
12
+ %w[get post delete put patch].each do |m|
13
+ define_method(m) do |path, options = {}, &block|
14
+ send_request(m.to_sym, path, options, &block)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def send_request(method, path, options, &block)
21
+ request = Request.new(options.merge!({
22
+ method: method,
23
+ token: token,
24
+ url: "#{Emites.configuration.url}#{path}",
25
+ user_agent: Emites.configuration.user_agent
26
+ }))
27
+
28
+ response = Response.new(request.run)
29
+
30
+ response.resolve!(&block)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,53 @@
1
+ module Emites
2
+ class Request
3
+
4
+ def initialize(args)
5
+ @args = args
6
+ end
7
+
8
+ def run
9
+ request.run
10
+ request.response
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :args
16
+
17
+ def request
18
+ @request ||= Typhoeus::Request.new(args[:url], options)
19
+ end
20
+
21
+ def options
22
+ {
23
+ method: args[:method],
24
+ params: args[:params],
25
+ body: body,
26
+ headers: headers,
27
+ userpwd: token,
28
+ accept_encoding: "gzip"
29
+ }.reject {|k,v| v.nil?}
30
+ end
31
+
32
+ def headers
33
+ headers = args.fetch(:headers) { {} }
34
+
35
+ {
36
+ "Accept" => "application/json",
37
+ "Content-Type" => "application/json",
38
+ "User-Agent" => args[:user_agent]
39
+ }.merge(headers)
40
+ end
41
+
42
+ def body
43
+ body = args[:body]
44
+ body = MultiJson.dump(body) if body.is_a?(Hash)
45
+ body
46
+ end
47
+
48
+ def token
49
+ "#{args[:token]}:x"
50
+ end
51
+
52
+ end
53
+ end