br_nfe 1.0.2 → 1.1.0
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.
- checksums.yaml +4 -4
- data/README.markdown +1 -1
- data/lib/br_nfe/base.rb +31 -15
- data/lib/br_nfe/servico/betha/v2/gateway.rb +11 -2
- data/lib/br_nfe/servico/rps.rb +5 -0
- data/lib/br_nfe/version.rb +2 -2
- data/lib/br_nfe.rb +0 -1
- data/test/br_nfe/base_test.rb +28 -24
- data/test/br_nfe/servico/betha/v1/cancelamento_nfs_test.rb +5 -1
- data/test/br_nfe/servico/betha/v1/recepcao_lote_rps_test.rb +5 -1
- data/test/br_nfe/servico/betha/v2/cancelamento_nfs_test.rb +5 -1
- data/test/br_nfe/servico/betha/v2/envio_lote_rps_sincrono_test.rb +6 -1
- data/test/br_nfe/servico/betha/v2/gera_nfse_test.rb +7 -3
- data/test/br_nfe/servico/betha/v2/recepcao_lote_rps_test.rb +6 -1
- data/test/br_nfe/servico/betha/v2/substituicao_nfse_test.rb +6 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11fb152b3151c62d8608888d5ba95174e4d2a435
|
4
|
+
data.tar.gz: 23472fba54d77618bd59b9793295971597513638
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 :
|
7
|
-
attr_accessor :
|
8
|
-
attr_accessor :
|
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 :
|
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
|
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
|
19
|
-
# Caso tenha o
|
20
|
-
def
|
21
|
-
@
|
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
|
64
|
-
@
|
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
|
69
|
-
@
|
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
|
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 =
|
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
|
-
|
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
|
-
|
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?
|
data/lib/br_nfe/servico/rps.rb
CHANGED
@@ -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
|
data/lib/br_nfe/version.rb
CHANGED
@@ -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 =
|
5
|
-
PATCH =
|
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
data/test/br_nfe/base_test.rb
CHANGED
@@ -7,19 +7,23 @@ describe BrNfe::Base do
|
|
7
7
|
let(:emitente) { FactoryGirl.build(:emitente) }
|
8
8
|
|
9
9
|
before do
|
10
|
-
subject.stubs(:
|
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(:
|
15
|
+
before { subject.unstub(:certificate_pkcs12) }
|
16
16
|
it "deve ser obrigatorio se certificado_obrigatorio? for true" do
|
17
|
-
subject.
|
18
|
-
|
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.
|
22
|
-
|
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 "#
|
68
|
+
describe "#certificate_pkcs12_value" do
|
65
69
|
it "se tiver algum valor setado deve retornar esse valor" do
|
66
|
-
subject.
|
67
|
-
subject.
|
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.
|
74
|
+
subject.certificate_pkcs12_path = "algum/lugar.pfx"
|
71
75
|
File.expects(:read).with("algum/lugar.pfx").returns("valor do arquivo")
|
72
|
-
subject.
|
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.
|
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 "#
|
267
|
+
describe "#certificate_pkcs12" do
|
264
268
|
before do
|
265
|
-
subject.unstub(:
|
269
|
+
subject.unstub(:certificate_pkcs12)
|
266
270
|
end
|
267
|
-
it "deve ler o
|
268
|
-
subject.assign_attributes(
|
269
|
-
OpenSSL::PKCS12.expects(:new).with("CERTIFICADO", 'pWd123').returns('
|
270
|
-
subject.
|
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
|
273
|
-
subject.instance_variable_set(:@
|
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.
|
279
|
+
subject.certificate_pkcs12.must_equal certificado
|
276
280
|
end
|
277
|
-
it "posso setar o
|
278
|
-
subject.
|
279
|
-
subject.
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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,
|
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
|
-
|
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
|
-
|
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,
|
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
|
-
|
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
|
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-
|
11
|
+
date: 2015-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|