br_nfe 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 95a7593fa277c48b625c3acf17b6f8feb0bf5989
4
- data.tar.gz: d96d3e26d74c21df7d0195f1091d6b80b6dfa1bb
3
+ metadata.gz: 11fb152b3151c62d8608888d5ba95174e4d2a435
4
+ data.tar.gz: 23472fba54d77618bd59b9793295971597513638
5
5
  SHA512:
6
- metadata.gz: 3b6cd55de324a626cff4dbe8dc4afd9a0498e31263bd366fecbd43b7a3378986effa5a029267fe157bed1b5c39bcb1978ca0e9871bc889826faf54a4f34e4968
7
- data.tar.gz: d7db379de7593dff9b50fcb6d63ee158daf540b542ed180149f13ad96d56707ba24d03f0b07fad0dc7516189e3ce7cfdc317c44fb58ec1e3d80501cefefa98ca
6
+ metadata.gz: 732f08b5b62348717188127aca18718c09063a5a56014512825e12fa4528f0a0a37578a0ebb07febeac1d491e212e8ff3bcc689eb0ba73d5ced80d40efe0fe6b
7
+ data.tar.gz: 9cdb3eda197abddafaf1625dff5b4d275cae4cbf6ca7cab83e4dd66e34f286483e8943b415c213cf69c698ae53c38684a18e45cc6c024b2b7157aff4cbc49f2f
data/README.markdown CHANGED
@@ -8,8 +8,8 @@
8
8
  # **BrNfe**
9
9
  Gem para emissão de notas fiscais eletrônicas.
10
10
 
11
- ## Versão 1.0.1
12
11
  **Motivo e Objetivo**
12
+
13
13
  Devido a falta de padronização dos parâmetros e a forma de envio e resposta na transmissão de Notas Fiscais de Serviços (NFS), esta gem vem com o objetivo de obter uma forma padronizada dessa tarefa, e assim, facilitando a vida de muitos desenvolvedores.
14
14
 
15
15
  **O que essa gem faz?**
data/lib/br_nfe/base.rb CHANGED
@@ -3,22 +3,22 @@ module BrNfe
3
3
 
4
4
  include BrNfe::Helper::HaveEmitente
5
5
 
6
- attr_accessor :certificado_password
7
- attr_accessor :certificado_path
8
- attr_accessor :certificado_value
6
+ attr_accessor :certificate_pkcs12_password
7
+ attr_accessor :certificate_pkcs12_path
8
+ attr_accessor :certificate_pkcs12_value
9
9
 
10
10
  validate :validar_emitente
11
- validates :certificado, presence: true, if: :certificado_obrigatorio?
11
+ validates :certificate, :certificate_key, presence: true, if: :certificado_obrigatorio?
12
12
 
13
- # Método que deve ser sobrescrito para as ações que necessitam do certificado para assinatura
13
+ # Método que deve ser sobrescrito para as ações que necessitam do certificate_pkcs12 para assinatura
14
14
  def certificado_obrigatorio?
15
15
  false
16
16
  end
17
17
 
18
- # Caso não tenha o certificado salvo em arquivo, pode setar a string do certificado direto pelo atributo certificado_value
19
- # Caso tenha o certificado em arquivo, basta setar o atributo certificado_path e deixar o atributo certificado_value em branco
20
- def certificado_value
21
- @certificado_value ||= File.read(certificado_path)
18
+ # Caso não tenha o certificate_pkcs12 salvo em arquivo, pode setar a string do certificate_pkcs12 direto pelo atributo certificate_pkcs12_value
19
+ # Caso tenha o certificate_pkcs12 em arquivo, basta setar o atributo certificate_pkcs12_path e deixar o atributo certificate_pkcs12_value em branco
20
+ def certificate_pkcs12_value
21
+ @certificate_pkcs12_value ||= File.read(certificate_pkcs12_path)
22
22
  end
23
23
 
24
24
  attr_accessor :env
@@ -60,13 +60,13 @@ module BrNfe
60
60
  {}
61
61
  end
62
62
 
63
- def certificado
64
- @certificado ||= OpenSSL::PKCS12.new(certificado_value, certificado_password)
63
+ def certificate_pkcs12
64
+ @certificate_pkcs12 ||= OpenSSL::PKCS12.new(certificate_pkcs12_value, certificate_pkcs12_password)
65
65
  rescue
66
66
  end
67
67
 
68
- def certificado=(value)
69
- @certificado = value
68
+ def certificate_pkcs12=(value)
69
+ @certificate_pkcs12 = value
70
70
  end
71
71
 
72
72
  def wsdl_encoding
@@ -89,6 +89,22 @@ module BrNfe
89
89
  })
90
90
  end
91
91
 
92
+ def certificate=(value)
93
+ @certificate = value
94
+ end
95
+
96
+ def certificate
97
+ @certificate ||= certificate_pkcs12.try :certificate
98
+ end
99
+
100
+ def certificate_key
101
+ @certificate_key ||= certificate_pkcs12.try :key
102
+ end
103
+
104
+ def certificate_key=(value)
105
+ @certificate_key = value
106
+ end
107
+
92
108
  private
93
109
 
94
110
  def tag_cpf_cnpj(xml, cpf_cnpj)
@@ -113,7 +129,7 @@ module BrNfe
113
129
 
114
130
  signature.KeyInfo {
115
131
  signature.X509Data {
116
- signature.X509Certificate certificado.certificate.to_s.gsub(/\-\-\-\-\-[A-Z]+ CERTIFICATE\-\-\-\-\-/, "").gsub(/\n/,"")
132
+ signature.X509Certificate certificate.to_s.gsub(/\-\-\-\-\-[A-Z]+ CERTIFICATE\-\-\-\-\-/, "").gsub(/\n/,"")
117
133
  }
118
134
  }
119
135
  end
@@ -140,7 +156,7 @@ module BrNfe
140
156
 
141
157
  def xml_signature_value(xml)
142
158
  sign_canon = canonicalize(xml)
143
- signature_hash = certificado.key.sign(OpenSSL::Digest::SHA1.new, sign_canon)
159
+ signature_hash = certificate_key.sign(OpenSSL::Digest::SHA1.new, sign_canon)
144
160
  remove_quebras Base64.encode64( signature_hash )
145
161
  end
146
162
 
@@ -121,12 +121,21 @@ module BrNfe
121
121
  xml.IssRetido value_true_false(rps.iss_retido?)
122
122
  xml.ResponsavelRetencao "#{rps.responsavel_retencao}".max_size(1) unless rps.responsavel_retencao.blank?
123
123
  xml.ItemListaServico BrNfe::Helper.only_number(rps.item_lista_servico).rjust(4,'0').max_size(5) unless rps.item_lista_servico.blank?
124
- xml.CodigoCnae BrNfe::Helper.only_number(rps.codigo_cnae).max_size(7) unless rps.codigo_cnae.blank?
124
+
125
+ # Não devo enviar o CNAE na base de testes pois o municipio enviado será 0 (zero)
126
+ if env != :test
127
+ xml.CodigoCnae BrNfe::Helper.only_number(rps.codigo_cnae).max_size(7) unless rps.codigo_cnae.blank?
128
+ end
129
+
125
130
  xml.CodigoTributacaoMunicipio "#{rps.codigo_tributacao_municipio}".max_size(20) unless rps.codigo_tributacao_municipio.blank?
126
131
  xml.Discriminacao "#{rps.discriminacao}".max_size(2_000).remove_accents
127
- xml.CodigoMunicipio BrNfe::Helper.only_number(rps.codigo_municipio).max_size(7)
132
+
133
+ # Na base de testes devo enviar o código do município como 0 (zero)
134
+ xml.CodigoMunicipio (env == :test ? 0 : BrNfe::Helper.only_number(rps.codigo_municipio).max_size(7))
135
+
128
136
  # Não posso enviar o CodigoPais se a exigibilidade_iss não for 4 (exportação) - by bethagambis.com
129
137
  xml.CodigoPais BrNfe::Helper.only_number(rps.codigo_pais).max_size(4) if !rps.codigo_pais.blank? && rps.exigibilidade_iss == '4'
138
+
130
139
  xml.ExigibilidadeISS "#{rps.exigibilidade_iss}".max_size(2)
131
140
  xml.MunicipioIncidencia BrNfe::Helper.only_number(rps.municipio_incidencia).max_size(7) unless rps.municipio_incidencia.blank?
132
141
  xml.NumeroProcesso rps.numero_processo.max_size(30) unless rps.numero_processo.blank?
@@ -14,6 +14,7 @@ module BrNfe
14
14
  record.validates :data_emissao, :item_lista_servico, :discriminacao, :codigo_municipio,
15
15
  :valor_servicos, :base_calculo, presence: true
16
16
  record.validates :valor_iss, :aliquota, presence: true, unless: :iss_retido?
17
+ record.validates :municipio_incidencia, presence: true, if: :municipio_incidencia_obrigatorio?
17
18
 
18
19
  record.validates :valor_servicos, :valor_deducoes, :valor_pis, :valor_cofins, :valor_inss, :valor_ir,
19
20
  :valor_csll, :outras_retencoes, :valor_iss, :aliquota, :base_calculo,
@@ -98,6 +99,10 @@ module BrNfe
98
99
  destinatario.errors.full_messages.map{|msg| errors.add(:base, "Destinatário: #{msg}") }
99
100
  end
100
101
  end
102
+
103
+ def municipio_incidencia_obrigatorio?
104
+ "#{exigibilidade_iss}".in?(['1','01','6','06','7','07'])
105
+ end
101
106
  end
102
107
  end
103
108
  end
@@ -1,8 +1,8 @@
1
1
  module BrNfe
2
2
  module Version
3
3
  MAJOR = 1 #inclui alterações de API e pode quebrar compatibilidade com versões anteriores
4
- MINOR = 0 #inclui novas funcionalidades, sem quebrar APIs existentes
5
- PATCH = 2 #corrige bugs ou traz melhorias em implementações já existentes
4
+ MINOR = 1 #inclui novas funcionalidades, sem quebrar APIs existentes
5
+ PATCH = 0 #corrige bugs ou traz melhorias em implementações já existentes
6
6
  CURRENT = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
7
  end
8
8
  end
data/lib/br_nfe.rb CHANGED
@@ -41,7 +41,6 @@ module BrNfe
41
41
  autoload :Destinatario
42
42
  autoload :Response
43
43
  autoload :Base
44
- autoload :Seed
45
44
  autoload :CondicaoPagamento
46
45
 
47
46
  module Servico
@@ -7,19 +7,23 @@ describe BrNfe::Base do
7
7
  let(:emitente) { FactoryGirl.build(:emitente) }
8
8
 
9
9
  before do
10
- subject.stubs(:certificado).returns(certificado)
10
+ subject.stubs(:certificate_pkcs12).returns(certificado)
11
11
  end
12
12
 
13
13
  describe "validations" do
14
14
  context "obrigatoriedade do certificado" do
15
- before { subject.unstub(:certificado) }
15
+ before { subject.unstub(:certificate_pkcs12) }
16
16
  it "deve ser obrigatorio se certificado_obrigatorio? for true" do
17
- subject.expects(:certificado_obrigatorio?).returns(true)
18
- must validate_presence_of(:certificado)
17
+ subject.stubs(:certificado_obrigatorio?).returns(true)
18
+ subject.certificate_pkcs12 = nil
19
+ must validate_presence_of(:certificate)
20
+ must validate_presence_of(:certificate_key)
19
21
  end
20
22
  it "não deve ser obrigatorio se certificado_obrigatorio? for false" do
21
- subject.expects(:certificado_obrigatorio?).returns(false)
22
- wont validate_presence_of(:certificado)
23
+ subject.stubs(:certificado_obrigatorio?).returns(false)
24
+ subject.certificate_pkcs12 = nil
25
+ wont validate_presence_of(:certificate)
26
+ wont validate_presence_of(:certificate_key)
23
27
  end
24
28
  end
25
29
  context "validação do emitente" do
@@ -61,15 +65,15 @@ describe BrNfe::Base do
61
65
  subject.certificado_obrigatorio?.must_equal false
62
66
  end
63
67
 
64
- describe "#certificado_value" do
68
+ describe "#certificate_pkcs12_value" do
65
69
  it "se tiver algum valor setado deve retornar esse valor" do
66
- subject.certificado_value = "algum valor"
67
- subject.certificado_value.must_equal "algum valor"
70
+ subject.certificate_pkcs12_value = "algum valor"
71
+ subject.certificate_pkcs12_value.must_equal "algum valor"
68
72
  end
69
73
  it "se não tiver um valor deve carregar o arquivo setado no atributo certificado_path" do
70
- subject.certificado_path = "algum/lugar.pfx"
74
+ subject.certificate_pkcs12_path = "algum/lugar.pfx"
71
75
  File.expects(:read).with("algum/lugar.pfx").returns("valor do arquivo")
72
- subject.certificado_value.must_equal "valor do arquivo"
76
+ subject.certificate_pkcs12_value.must_equal "valor do arquivo"
73
77
  end
74
78
  end
75
79
 
@@ -203,7 +207,7 @@ describe BrNfe::Base do
203
207
  it "deve assinar um xml com o certificado" do
204
208
  sh1 = OpenSSL::Digest::SHA1.new
205
209
  OpenSSL::Digest::SHA1.stubs(:new).returns(sh1)
206
- subject.certificado.key.expects(:sign).with(sh1, "<Um><Xml> Com valor</Xml></Um>").returns('mv\xBFH\xE3\xF5Z\x0F\xE1*0D')
210
+ subject.certificate_pkcs12.key.expects(:sign).with(sh1, "<Um><Xml> Com valor</Xml></Um>").returns('mv\xBFH\xE3\xF5Z\x0F\xE1*0D')
207
211
 
208
212
  subject.send(:xml_signature_value, xml).must_equal 'bXZceEJGSFx4RTNceEY1Wlx4MEZceEUxKjBE'
209
213
  end
@@ -260,23 +264,23 @@ describe BrNfe::Base do
260
264
  end
261
265
  end
262
266
 
263
- describe "#certificado" do
267
+ describe "#certificate_pkcs12" do
264
268
  before do
265
- subject.unstub(:certificado)
269
+ subject.unstub(:certificate_pkcs12)
266
270
  end
267
- it "deve ler o certificado PKCS12 do atributo certificado_value e com a senha do certificado_password" do
268
- subject.assign_attributes(certificado_value: "CERTIFICADO", certificado_password: 'pWd123')
269
- OpenSSL::PKCS12.expects(:new).with("CERTIFICADO", 'pWd123').returns('certificado')
270
- subject.certificado.must_equal 'certificado'
271
+ it "deve ler o certificate_pkcs12 PKCS12 do atributo certificate_pkcs12_value e com a senha do certificate_pkcs12_password" do
272
+ subject.assign_attributes(certificate_pkcs12: nil, certificate_pkcs12_value: "CERTIFICADO", certificate_pkcs12_password: 'pWd123')
273
+ OpenSSL::PKCS12.expects(:new).with("CERTIFICADO", 'pWd123').returns('certificate_pkcs12')
274
+ subject.certificate_pkcs12.must_equal 'certificate_pkcs12'
271
275
  end
272
- it "se já tem um certificado na variavel @certificado não deve ler novamente do PKCS12" do
273
- subject.instance_variable_set(:@certificado, certificado)
276
+ it "se já tem um certificate_pkcs12 na variavel @certificate_pkcs12 não deve ler novamente do PKCS12" do
277
+ subject.instance_variable_set(:@certificate_pkcs12, certificado)
274
278
  OpenSSL::PKCS12.expects(:new).never
275
- subject.certificado.must_equal certificado
279
+ subject.certificate_pkcs12.must_equal certificado
276
280
  end
277
- it "posso setar o certificado" do
278
- subject.certificado = 'certificado 123'
279
- subject.certificado.must_equal 'certificado 123'
281
+ it "posso setar o certificate_pkcs12" do
282
+ subject.certificate_pkcs12 = 'certificate_pkcs12 123'
283
+ subject.certificate_pkcs12.must_equal 'certificate_pkcs12 123'
280
284
  end
281
285
  end
282
286
 
@@ -11,7 +11,11 @@ describe BrNfe::Servico::Betha::V1::CancelamentoNfs do
11
11
  describe "validations" do
12
12
  it { must validate_presence_of(:numero_nfse) }
13
13
  it { must validate_presence_of(:codigo_cancelamento) }
14
- it { must validate_presence_of(:certificado) }
14
+ context "validações do certificado" do
15
+ before { subject.certificate_pkcs12 = nil }
16
+ it { must validate_presence_of(:certificate) }
17
+ it { must validate_presence_of(:certificate_key) }
18
+ end
15
19
  end
16
20
 
17
21
  describe "#wsdl" do
@@ -12,7 +12,11 @@ describe BrNfe::Servico::Betha::V1::RecepcaoLoteRps do
12
12
 
13
13
  describe "validations" do
14
14
  it { must validate_presence_of(:numero_lote_rps) }
15
- it { must validate_presence_of(:certificado) }
15
+ context "validações do certificado" do
16
+ before { subject.certificate_pkcs12 = nil }
17
+ it { must validate_presence_of(:certificate) }
18
+ it { must validate_presence_of(:certificate_key) }
19
+ end
16
20
 
17
21
  it "deve chamar o metodo validar_lote_rps" do
18
22
  subject.expects(:validar_lote_rps)
@@ -13,7 +13,11 @@ describe BrNfe::Servico::Betha::V2::CancelamentoNfs do
13
13
  describe "validations" do
14
14
  it { must validate_presence_of(:numero_nfse) }
15
15
  it { must validate_presence_of(:codigo_cancelamento) }
16
- it { must validate_presence_of(:certificado) }
16
+ context "validações do certificado" do
17
+ before { subject.certificate_pkcs12 = nil }
18
+ it { must validate_presence_of(:certificate) }
19
+ it { must validate_presence_of(:certificate_key) }
20
+ end
17
21
  end
18
22
 
19
23
  describe "#method_wsdl" do
@@ -10,7 +10,12 @@ describe BrNfe::Servico::Betha::V2::EnvioLoteRpsSincrono do
10
10
 
11
11
  describe "validations" do
12
12
  it { must validate_presence_of(:numero_lote_rps) }
13
- it { must validate_presence_of(:certificado) }
13
+
14
+ context "validações do certificado" do
15
+ before { subject.certificate_pkcs12 = nil }
16
+ it { must validate_presence_of(:certificate) }
17
+ it { must validate_presence_of(:certificate_key) }
18
+ end
14
19
 
15
20
  it "deve chamar o metodo validar_lote_rps" do
16
21
  subject.expects(:validar_lote_rps)
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  describe BrNfe::Servico::Betha::V2::GeraNfse do
4
- subject { FactoryGirl.build(:br_nfe_servico_betha_v2_gera_nfse, emitente: emitente, rps: rps, certificado: certificado) }
4
+ subject { FactoryGirl.build(:br_nfe_servico_betha_v2_gera_nfse, emitente: emitente, rps: rps, certificate_pkcs12: certificado) }
5
5
  let(:emitente) { FactoryGirl.build(:emitente) }
6
6
  let(:rps) { FactoryGirl.build(:br_nfe_rps) }
7
7
  let(:certificado) { Certificado.new }
@@ -11,8 +11,12 @@ describe BrNfe::Servico::Betha::V2::GeraNfse do
11
11
  end
12
12
 
13
13
  describe "validations" do
14
- it { must validate_presence_of(:certificado) }
15
-
14
+
15
+ context "validações do certificado" do
16
+ before { subject.certificate_pkcs12 = nil }
17
+ it { must validate_presence_of(:certificate) }
18
+ it { must validate_presence_of(:certificate_key) }
19
+ end
16
20
  context "deve validar o rps" do
17
21
  it "quando o rps for válido não deve setar nenhuma mensagem no objeto" do
18
22
  rps.stubs(:errors).returns(stub(full_messages: ["Erro rps"]))
@@ -10,7 +10,12 @@ describe BrNfe::Servico::Betha::V2::RecepcaoLoteRps do
10
10
 
11
11
  describe "validations" do
12
12
  it { must validate_presence_of(:numero_lote_rps) }
13
- it { must validate_presence_of(:certificado) }
13
+
14
+ context "validações do certificado" do
15
+ before { subject.certificate_pkcs12 = nil }
16
+ it { must validate_presence_of(:certificate) }
17
+ it { must validate_presence_of(:certificate_key) }
18
+ end
14
19
 
15
20
  it "deve chamar o metodo validar_lote_rps" do
16
21
  subject.expects(:validar_lote_rps)
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  describe BrNfe::Servico::Betha::V2::SubstituicaoNfse do
4
- subject { FactoryGirl.build(:br_nfe_servico_betha_v2_substituicao_nfse, emitente: emitente, rps: rps, certificado: certificado) }
4
+ subject { FactoryGirl.build(:br_nfe_servico_betha_v2_substituicao_nfse, emitente: emitente, rps: rps, certificate_pkcs12: certificado) }
5
5
  let(:emitente) { FactoryGirl.build(:emitente) }
6
6
  let(:rps) { FactoryGirl.build(:br_nfe_rps) }
7
7
  let(:certificado) { Certificado.new }
@@ -11,7 +11,11 @@ describe BrNfe::Servico::Betha::V2::SubstituicaoNfse do
11
11
  end
12
12
 
13
13
  describe "validations" do
14
- it { must validate_presence_of(:certificado) }
14
+ context "validações do certificado" do
15
+ before { subject.certificate_pkcs12 = nil }
16
+ it { must validate_presence_of(:certificate) }
17
+ it { must validate_presence_of(:certificate_key) }
18
+ end
15
19
  it { must validate_presence_of(:numero_nfse) }
16
20
  it { must validate_presence_of(:codigo_cancelamento) }
17
21
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: br_nfe
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno M. Mergen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-29 00:00:00.000000000 Z
11
+ date: 2015-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake