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