br_nfe 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -1
- data/README.markdown +263 -1
- data/br_nfe.gemspec +14 -5
- data/lib/br_nfe/base.rb +6 -1
- data/lib/br_nfe/helper/cpf_cnpj.rb +0 -5
- data/lib/br_nfe/helper/have_address.rb +1 -5
- data/lib/br_nfe/helper/have_rps.rb +7 -0
- data/lib/br_nfe/servico/betha/base.rb +52 -41
- data/lib/br_nfe/servico/betha/build_response.rb +141 -0
- data/lib/br_nfe/servico/betha/v1/build_response.rb +4 -102
- data/lib/br_nfe/servico/betha/v1/consulta_lote_rps.rb +3 -1
- data/lib/br_nfe/servico/betha/v1/consulta_nfs_por_rps.rb +5 -2
- data/lib/br_nfe/servico/betha/v1/consulta_nfse.rb +2 -1
- data/lib/br_nfe/servico/betha/v1/gateway.rb +66 -56
- data/lib/br_nfe/servico/betha/v1/recepcao_lote_rps.rb +16 -8
- data/lib/br_nfe/servico/betha/v2/build_response.rb +159 -0
- data/lib/br_nfe/servico/betha/v2/cancelamento_nfs.rb +8 -3
- data/lib/br_nfe/servico/betha/v2/consulta_lote_rps.rb +7 -4
- data/lib/br_nfe/servico/betha/v2/consulta_nfse_por_rps.rb +5 -5
- data/lib/br_nfe/servico/betha/v2/envio_lote_rps_sincrono.rb +7 -3
- data/lib/br_nfe/servico/betha/v2/gateway.rb +79 -56
- data/lib/br_nfe/servico/betha/v2/gera_nfse.rb +8 -3
- data/lib/br_nfe/servico/betha/v2/recepcao_lote_rps.rb +9 -4
- data/lib/br_nfe/servico/betha/v2/substituicao_nfse.rb +8 -4
- data/lib/br_nfe/servico/response/nota_fiscal.rb +13 -4
- data/lib/br_nfe/servico/rps.rb +2 -2
- data/lib/br_nfe/version.rb +1 -1
- data/lib/br_nfe.rb +2 -1
- data/test/br_nfe/base_test.rb +55 -1
- data/test/br_nfe/destinatario_test.rb +19 -0
- data/test/br_nfe/emitente_test.rb +20 -0
- data/test/br_nfe/endereco_test.rb +9 -0
- data/test/br_nfe/helper/cpf_cnpj_test.rb +61 -0
- data/test/br_nfe/servico/base_test.rb +28 -0
- data/test/br_nfe/servico/betha/base_test.rb +61 -32
- data/test/br_nfe/servico/betha/v1/build_response_test.rb +6 -7
- data/test/br_nfe/servico/betha/v1/cancelamento_nfs_test.rb +6 -0
- data/test/br_nfe/servico/betha/v1/consulta_lote_rps_test.rb +4 -0
- data/test/br_nfe/servico/betha/v1/consulta_nfse_test.rb +17 -0
- data/test/br_nfe/servico/betha/v1/gateway_test.rb +17 -40
- data/test/br_nfe/servico/betha/v1/recepcao_lote_rps_test.rb +12 -2
- data/test/br_nfe/servico/betha/v2/cancelamento_nfs_test.rb +40 -0
- data/test/br_nfe/servico/betha/v2/consulta_lote_rps_test.rb +38 -0
- data/test/br_nfe/servico/betha/v2/consulta_nfse_por_rps_test.rb +36 -0
- data/test/br_nfe/servico/betha/v2/envio_lote_rps_sincrono_test.rb +46 -0
- data/test/br_nfe/servico/betha/v2/gateway_test.rb +372 -0
- data/test/br_nfe/servico/betha/v2/gera_nfse_test.rb +58 -0
- data/test/br_nfe/servico/betha/v2/recepcao_lote_rps_test.rb +103 -0
- data/test/br_nfe/servico/betha/v2/substituicao_nfse_test.rb +80 -0
- data/test/br_nfe/servico/intermediario_test.rb +16 -0
- data/test/br_nfe/servico/rps_test.rb +141 -0
- data/test/factories/servico/betha/v1/gateway.rb +1 -1
- data/test/factories/servico/betha/v2/cancelamento_nfs.rb +7 -0
- data/test/factories/servico/betha/v2/consulta_lote_rps.rb +6 -0
- data/test/factories/servico/betha/v2/consulta_nfse_por_rps.rb +6 -0
- data/test/factories/servico/betha/v2/envio_lote_rps_sincrono.rb +5 -0
- data/test/factories/servico/betha/v2/gateway.rb +5 -0
- data/test/factories/servico/betha/v2/gera_nfse.rb +6 -0
- data/test/factories/servico/betha/v2/recepcao_lote_rps.rb +5 -0
- data/test/factories/servico/betha/v2/substituicao_nfse.rb +8 -0
- metadata +50 -17
- data/Gemfile +0 -15
- data/Rakefile +0 -13
- data/lib/br_nfe/seed.rb +0 -195
- data/lib/br_nfe/servico/betha/v2/response.rb +0 -23
- data/test/certificado.rb +0 -12
- data/test/test_helper.rb +0 -39
@@ -31,7 +31,13 @@ module BrNfe
|
|
31
31
|
|
32
32
|
def set_response(resp)
|
33
33
|
method_response = (method_wsdl.to_s + "_response").to_sym
|
34
|
-
@
|
34
|
+
@builder = BrNfe::Servico::Betha::V2::BuildResponse.new(xml: resp.hash[:envelope][:body][method_response][:return], nfe_method: method_wsdl)
|
35
|
+
@original_response = @builder.messages
|
36
|
+
@response = @builder.response
|
37
|
+
end
|
38
|
+
|
39
|
+
def builder
|
40
|
+
@builder
|
35
41
|
end
|
36
42
|
|
37
43
|
def cabecalho
|
@@ -49,10 +55,14 @@ module BrNfe
|
|
49
55
|
def content_xml
|
50
56
|
Nokogiri::XML::Builder.new do
|
51
57
|
nfseDadosMsg do
|
52
|
-
cdata(
|
58
|
+
cdata(canonical_xml_builder)
|
53
59
|
end
|
54
60
|
end.doc.root.to_s
|
55
61
|
end
|
62
|
+
|
63
|
+
def canonical_xml_builder
|
64
|
+
canonicalize xml_builder.doc.root
|
65
|
+
end
|
56
66
|
|
57
67
|
private
|
58
68
|
|
@@ -64,88 +74,101 @@ module BrNfe
|
|
64
74
|
canonicalize xml.to_s
|
65
75
|
end
|
66
76
|
|
67
|
-
def
|
68
|
-
return unless intermediario
|
69
|
-
xml
|
70
|
-
xml.
|
71
|
-
xml.
|
72
|
-
|
77
|
+
def xml_intermediario_servico(intermediario)
|
78
|
+
return Nokogiri::XML::Builder.new unless intermediario
|
79
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
80
|
+
xml.Intermediario{
|
81
|
+
xml.IdentificacaoIntermediario{
|
82
|
+
xml.CpfCnpj{
|
83
|
+
tag_cpf_cnpj(xml, intermediario.cpf_cnpj)
|
84
|
+
}
|
85
|
+
xml.InscricaoMunicipal "#{intermediario.inscricao_municipal}".max_size(15) unless intermediario.inscricao_municipal.blank?
|
73
86
|
}
|
74
|
-
xml.
|
87
|
+
xml.RazaoSocial "#{intermediario.razao_social}".max_size(150)
|
75
88
|
}
|
76
|
-
|
77
|
-
}
|
89
|
+
end
|
78
90
|
end
|
79
91
|
|
80
|
-
def
|
81
|
-
|
82
|
-
xml.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
def tag_dados_servico(xml, rps)
|
90
|
-
xml.Servico {
|
91
|
-
xml.Valores {
|
92
|
-
xml.ValorServicos value_monetary(rps.valor_servicos, 2)
|
93
|
-
xml.ValorDeducoes value_monetary(rps.valor_deducoes, 2) unless rps.valor_deducoes.blank?
|
94
|
-
xml.ValorPis value_monetary(rps.valor_pis, 2) unless rps.valor_pis.blank?
|
95
|
-
xml.ValorCofins value_monetary(rps.valor_cofins, 2) unless rps.valor_cofins.blank?
|
96
|
-
xml.ValorInss value_monetary(rps.valor_inss, 2) unless rps.valor_inss.blank?
|
97
|
-
xml.ValorIr value_monetary(rps.valor_ir, 2) unless rps.valor_ir.blank?
|
98
|
-
xml.ValorCsll value_monetary(rps.valor_csll, 2) unless rps.valor_csll.blank?
|
99
|
-
xml.OutrasRetencoes value_monetary(rps.outras_retencoes, 2) unless rps.outras_retencoes.blank?
|
100
|
-
xml.ValorIss value_monetary(rps.valor_iss, 2) unless rps.valor_iss.blank?
|
101
|
-
xml.Aliquota value_monetary(rps.aliquota, 2) unless rps.aliquota.blank?
|
102
|
-
xml.DescontoIncondicionado value_monetary(rps.desconto_incondicionado, 2) unless rps.desconto_incondicionado.blank?
|
103
|
-
xml.DescontoCondicionado value_monetary(rps.desconto_condicionado, 2) unless rps.desconto_condicionado.blank?
|
92
|
+
def xml_prestador
|
93
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
94
|
+
xml.Prestador{
|
95
|
+
xml.CpfCnpj{
|
96
|
+
tag_cpf_cnpj(xml, emitente.cnpj)
|
97
|
+
}
|
98
|
+
xml.InscricaoMunicipal "#{emitente.inscricao_municipal}".max_size(15) if !emitente.inscricao_municipal.blank? && env == :production
|
104
99
|
}
|
100
|
+
end
|
101
|
+
end
|
105
102
|
|
106
|
-
|
107
|
-
|
108
|
-
xml.
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
103
|
+
def xml_dados_servico(rps)
|
104
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
105
|
+
xml.Servico {
|
106
|
+
xml.Valores {
|
107
|
+
xml.ValorServicos value_monetary(rps.valor_servicos, 2)
|
108
|
+
xml.ValorDeducoes value_monetary(rps.valor_deducoes, 2) unless rps.valor_deducoes.blank?
|
109
|
+
xml.ValorPis value_monetary(rps.valor_pis, 2) unless rps.valor_pis.blank?
|
110
|
+
xml.ValorCofins value_monetary(rps.valor_cofins, 2) unless rps.valor_cofins.blank?
|
111
|
+
xml.ValorInss value_monetary(rps.valor_inss, 2) unless rps.valor_inss.blank?
|
112
|
+
xml.ValorIr value_monetary(rps.valor_ir, 2) unless rps.valor_ir.blank?
|
113
|
+
xml.ValorCsll value_monetary(rps.valor_csll, 2) unless rps.valor_csll.blank?
|
114
|
+
xml.OutrasRetencoes value_monetary(rps.outras_retencoes, 2) unless rps.outras_retencoes.blank?
|
115
|
+
xml.ValorIss value_monetary(rps.valor_iss, 2) unless rps.valor_iss.blank?
|
116
|
+
xml.Aliquota value_monetary(rps.aliquota, 2) unless rps.aliquota.blank?
|
117
|
+
xml.DescontoIncondicionado value_monetary(rps.desconto_incondicionado, 2) unless rps.desconto_incondicionado.blank?
|
118
|
+
xml.DescontoCondicionado value_monetary(rps.desconto_condicionado, 2) unless rps.desconto_condicionado.blank?
|
119
|
+
}
|
120
|
+
|
121
|
+
xml.IssRetido value_true_false(rps.iss_retido?)
|
122
|
+
xml.ResponsavelRetencao "#{rps.responsavel_retencao}".max_size(1) unless rps.responsavel_retencao.blank?
|
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?
|
125
|
+
xml.CodigoTributacaoMunicipio "#{rps.codigo_tributacao_municipio}".max_size(20) unless rps.codigo_tributacao_municipio.blank?
|
126
|
+
xml.Discriminacao "#{rps.discriminacao}".max_size(2_000).remove_accents
|
127
|
+
xml.CodigoMunicipio BrNfe::Helper.only_number(rps.codigo_municipio).max_size(7)
|
128
|
+
# Não posso enviar o CodigoPais se a exigibilidade_iss não for 4 (exportação) - by bethagambis.com
|
129
|
+
xml.CodigoPais BrNfe::Helper.only_number(rps.codigo_pais).max_size(4) if !rps.codigo_pais.blank? && rps.exigibilidade_iss == '4'
|
130
|
+
xml.ExigibilidadeISS "#{rps.exigibilidade_iss}".max_size(2)
|
131
|
+
xml.MunicipioIncidencia BrNfe::Helper.only_number(rps.municipio_incidencia).max_size(7) unless rps.municipio_incidencia.blank?
|
132
|
+
xml.NumeroProcesso rps.numero_processo.max_size(30) unless rps.numero_processo.blank?
|
133
|
+
}
|
134
|
+
end
|
119
135
|
end
|
120
136
|
|
121
137
|
def xml_inf_declaracao_prestacao_servico(rps)
|
122
138
|
Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
123
139
|
xml.InfDeclaracaoPrestacaoServico('Id' => "rps#{rps.numero}") {
|
124
140
|
xml.Rps {
|
125
|
-
|
141
|
+
# Identificação RPS
|
142
|
+
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_identificacao_rps(rps).doc.root.to_s )
|
126
143
|
|
127
144
|
xml.DataEmissao value_date(rps.data_emissao)
|
128
145
|
xml.Status "#{rps.status}".max_size(1)
|
129
146
|
|
130
|
-
|
147
|
+
# RPS subistituido
|
148
|
+
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_rps_substituido(rps).doc.root.to_s )
|
131
149
|
}
|
132
150
|
|
133
151
|
# Dia, mês e ano da prestação do serviço
|
134
152
|
# Quando houver RPS, a nota será gerada com base na <DataEmissao> do RPS, caso contrário utilizará a <Competencia>
|
135
153
|
xml.Competencia value_date(rps.competencia)
|
136
154
|
|
137
|
-
|
155
|
+
# Dados do(s) serviço(s)
|
156
|
+
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_dados_servico(rps).doc.root.to_s )
|
138
157
|
|
139
|
-
|
158
|
+
# Pestador / Emitente
|
159
|
+
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_prestador.doc.root.to_s )
|
140
160
|
|
141
|
-
|
161
|
+
# Tomador / Destinatário
|
162
|
+
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_dados_tomador(rps.destinatario).doc.root.to_s )
|
142
163
|
|
143
|
-
|
164
|
+
# Intermediario
|
165
|
+
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_intermediario_servico(rps.intermediario).doc.root.to_s )
|
144
166
|
|
145
|
-
|
167
|
+
# Dados Construção Civil
|
168
|
+
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_dados_construcao_civil(rps).doc.root.to_s )
|
146
169
|
|
147
170
|
# Código de identificação do regime especial de tributação: (1)Microempresa municipal, (2)Estimativa, (3)Sociedade de profissionais, (4)Cooperativa, (5)Microempresário Individual (MEI), (6)Microempresário e Empresa de Pequeno Porte (ME EPP) ,
|
148
|
-
xml.RegimeEspecialTributacao emitente.regime_especial_tributacao.max_size(2) unless emitente.regime_especial_tributacao.blank?
|
171
|
+
xml.RegimeEspecialTributacao "#{emitente.regime_especial_tributacao}".max_size(2) unless emitente.regime_especial_tributacao.blank?
|
149
172
|
|
150
173
|
xml.OptanteSimplesNacional value_true_false(emitente.optante_simples_nacional?) # (1)sim ----- (2)não
|
151
174
|
xml.IncentivoFiscal value_true_false(emitente.incentivo_fiscal?) # (1)sim ----- (2)não
|
@@ -5,6 +5,12 @@ module BrNfe
|
|
5
5
|
class GeraNfse < BrNfe::Servico::Betha::V2::Gateway
|
6
6
|
include BrNfe::Helper::HaveRps
|
7
7
|
|
8
|
+
def certificado_obrigatorio?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
validate :valida_rps_recepcao
|
13
|
+
|
8
14
|
def method_wsdl
|
9
15
|
:gerar_nfse
|
10
16
|
end
|
@@ -14,10 +20,9 @@ module BrNfe
|
|
14
20
|
xml.GerarNfseEnvio(xmlns: "http://www.betha.com.br/e-nota-contribuinte-ws") {
|
15
21
|
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_rps_assinado(rps).doc.root.to_s)
|
16
22
|
}
|
17
|
-
end
|
18
|
-
|
19
|
-
canonicalize xml
|
23
|
+
end
|
20
24
|
end
|
25
|
+
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
@@ -3,6 +3,14 @@ module BrNfe
|
|
3
3
|
module Betha
|
4
4
|
module V2
|
5
5
|
class RecepcaoLoteRps < BrNfe::Servico::Betha::V2::Gateway
|
6
|
+
|
7
|
+
validate :validar_lote_rps
|
8
|
+
validates :numero_lote_rps, presence: true
|
9
|
+
|
10
|
+
def certificado_obrigatorio?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
6
14
|
def method_wsdl
|
7
15
|
:recepcionar_lote_rps
|
8
16
|
end
|
@@ -15,11 +23,8 @@ module BrNfe
|
|
15
23
|
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_lote_rps.to_s )
|
16
24
|
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( assinatura_xml(xml_lote_rps.to_s, "#lote#{numero_lote_rps}") )
|
17
25
|
}
|
18
|
-
end
|
19
|
-
|
20
|
-
canonicalize xml
|
26
|
+
end
|
21
27
|
end
|
22
|
-
|
23
28
|
|
24
29
|
def lote_rps_xml
|
25
30
|
xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
@@ -5,6 +5,13 @@ module BrNfe
|
|
5
5
|
class SubstituicaoNfse < BrNfe::Servico::Betha::V2::Gateway
|
6
6
|
include BrNfe::Helper::HaveRps
|
7
7
|
|
8
|
+
validate :valida_rps_recepcao
|
9
|
+
validates :numero_nfse, :codigo_cancelamento, presence: true
|
10
|
+
|
11
|
+
def certificado_obrigatorio?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
8
15
|
def method_wsdl
|
9
16
|
:substituir_nfse
|
10
17
|
end
|
@@ -16,12 +23,9 @@ module BrNfe
|
|
16
23
|
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_substituicao.to_s )
|
17
24
|
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( assinatura_xml(xml_substituicao.to_s, "#substituicao") )
|
18
25
|
}
|
19
|
-
end
|
20
|
-
|
21
|
-
canonicalize xml
|
26
|
+
end
|
22
27
|
end
|
23
28
|
|
24
|
-
|
25
29
|
def xml_substituicao_nfse
|
26
30
|
Nokogiri::XML::Builder.new do |xml|
|
27
31
|
xml.SubstituicaoNfse(Id: "substituicao") {
|
@@ -17,9 +17,12 @@ module BrNfe
|
|
17
17
|
attr_accessor :rps_serie
|
18
18
|
attr_accessor :rps_tipo
|
19
19
|
attr_accessor :rps_situacao
|
20
|
+
attr_accessor :rps_substituido_numero
|
21
|
+
attr_accessor :rps_substituido_serie
|
22
|
+
attr_accessor :rps_substituido_tipo
|
20
23
|
|
21
|
-
attr_accessor :data_emissao_rps
|
22
|
-
attr_accessor :competencia
|
24
|
+
attr_accessor :data_emissao_rps # Datetime
|
25
|
+
attr_accessor :competencia #DateTime
|
23
26
|
attr_accessor :outras_informacoes
|
24
27
|
|
25
28
|
# dados dos serviços
|
@@ -37,11 +40,17 @@ module BrNfe
|
|
37
40
|
attr_accessor :valor_ir
|
38
41
|
attr_accessor :valor_csll
|
39
42
|
attr_accessor :iss_retido
|
43
|
+
attr_accessor :outras_retencoes
|
40
44
|
attr_accessor :valor_iss
|
41
45
|
attr_accessor :base_calculo
|
42
46
|
attr_accessor :aliquota
|
43
|
-
attr_accessor :
|
44
|
-
attr_accessor :
|
47
|
+
attr_accessor :valor_liquido # v2
|
48
|
+
attr_accessor :desconto_condicionado # v2
|
49
|
+
attr_accessor :desconto_incondicionado # v2
|
50
|
+
|
51
|
+
attr_accessor :responsavel_retencao
|
52
|
+
attr_accessor :numero_processo
|
53
|
+
attr_accessor :municipio_incidencia
|
45
54
|
|
46
55
|
# Orgão gerador
|
47
56
|
attr_accessor :orgao_gerador_municipio
|
data/lib/br_nfe/servico/rps.rb
CHANGED
@@ -89,13 +89,13 @@ module BrNfe
|
|
89
89
|
def validar_intermediario
|
90
90
|
return true unless intermediario
|
91
91
|
if intermediario.invalid?
|
92
|
-
intermediario.errors.full_messages.map{|msg| errors.add(:
|
92
|
+
intermediario.errors.full_messages.map{|msg| errors.add(:base, "Intermediário: #{msg}") }
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
96
|
def validar_destinatario
|
97
97
|
if destinatario.invalid?
|
98
|
-
destinatario.errors.full_messages.map{|msg| errors.add(:
|
98
|
+
destinatario.errors.full_messages.map{|msg| errors.add(:base, "Destinatário: #{msg}") }
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
data/lib/br_nfe/version.rb
CHANGED
@@ -2,7 +2,7 @@ module BrNfe
|
|
2
2
|
module Version
|
3
3
|
MAJOR = 1 #inclui alterações de API e pode quebrar compatibilidade com versões anteriores
|
4
4
|
MINOR = 0 #inclui novas funcionalidades, sem quebrar APIs existentes
|
5
|
-
PATCH =
|
5
|
+
PATCH = 1 #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
@@ -58,6 +58,7 @@ module BrNfe
|
|
58
58
|
module Betha
|
59
59
|
extend ActiveSupport::Autoload
|
60
60
|
autoload :Base
|
61
|
+
autoload :BuildResponse
|
61
62
|
module V1
|
62
63
|
extend ActiveSupport::Autoload
|
63
64
|
autoload :Gateway
|
@@ -72,7 +73,7 @@ module BrNfe
|
|
72
73
|
module V2
|
73
74
|
extend ActiveSupport::Autoload
|
74
75
|
autoload :Gateway
|
75
|
-
autoload :
|
76
|
+
autoload :BuildResponse
|
76
77
|
autoload :CancelamentoNfs
|
77
78
|
autoload :ConsultaNfsePorRps
|
78
79
|
autoload :EnvioLoteRpsSincrono
|
data/test/br_nfe/base_test.rb
CHANGED
@@ -10,6 +10,35 @@ describe BrNfe::Base do
|
|
10
10
|
subject.stubs(:certificado).returns(certificado)
|
11
11
|
end
|
12
12
|
|
13
|
+
describe "validations" do
|
14
|
+
context "obrigatoriedade do certificado" do
|
15
|
+
before { subject.unstub(:certificado) }
|
16
|
+
it "deve ser obrigatorio se certificado_obrigatorio? for true" do
|
17
|
+
subject.expects(:certificado_obrigatorio?).returns(true)
|
18
|
+
must validate_presence_of(:certificado)
|
19
|
+
end
|
20
|
+
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
|
+
end
|
24
|
+
end
|
25
|
+
context "validação do emitente" do
|
26
|
+
it "se emitente for válido" do
|
27
|
+
emitente.stubs(:errors).returns(stub(full_messages: ["Erro rps"]))
|
28
|
+
emitente.expects(:invalid?).returns(false)
|
29
|
+
subject.valid?.must_equal true
|
30
|
+
subject.errors.full_messages.must_equal( [] )
|
31
|
+
end
|
32
|
+
|
33
|
+
it "se emitente for inválido" do
|
34
|
+
emitente.stubs(:errors).returns(stub(full_messages: ["Erro rps"]))
|
35
|
+
emitente.expects(:invalid?).returns(true)
|
36
|
+
subject.valid?.must_equal false
|
37
|
+
subject.errors.full_messages.must_equal( ["Emitente: Erro rps"] )
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
13
42
|
describe "#emitente" do
|
14
43
|
include BrNfeTest::HelperTest::HaveEmitenteTest
|
15
44
|
end
|
@@ -24,6 +53,14 @@ describe BrNfe::Base do
|
|
24
53
|
end
|
25
54
|
end
|
26
55
|
|
56
|
+
describe "#wsdl_encoding" do
|
57
|
+
it { subject.wsdl_encoding.must_equal 'UTF-8' }
|
58
|
+
end
|
59
|
+
|
60
|
+
it "certificado_obrigatorio?" do
|
61
|
+
subject.certificado_obrigatorio?.must_equal false
|
62
|
+
end
|
63
|
+
|
27
64
|
describe "#certificado_value" do
|
28
65
|
it "se tiver algum valor setado deve retornar esse valor" do
|
29
66
|
subject.certificado_value = "algum valor"
|
@@ -46,6 +83,16 @@ describe BrNfe::Base do
|
|
46
83
|
end
|
47
84
|
end
|
48
85
|
|
86
|
+
describe "#original_response" do
|
87
|
+
it "deve retornar o valor da variavel @original_response" do
|
88
|
+
subject.instance_variable_set(:@original_response, 'valor')
|
89
|
+
subject.original_response.must_equal 'valor'
|
90
|
+
end
|
91
|
+
it "valor default" do
|
92
|
+
subject.original_response.must_be_nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
49
96
|
describe "#wsdl" do
|
50
97
|
it "deve dar um erro por default" do
|
51
98
|
assert_raises RuntimeError do
|
@@ -198,6 +245,8 @@ describe BrNfe::Base do
|
|
198
245
|
end
|
199
246
|
|
200
247
|
it "deve gerar o xml" do
|
248
|
+
certificado.stubs(:certificate).returns("-----BEGIN CERTIFICATE-----\nMCYwHAIBADAASDIHASDIASHDIAMAMGAQADAQAwAwYBAAMBAA==\n-----END CERTIFICATE-----\n")
|
249
|
+
|
201
250
|
subject.stubs(:signed_info).with(xml, 'URI123').returns(xml_signed_info)
|
202
251
|
subject.expects(:xml_signature_value).with('<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><Value>STUBADO</Value></Signature>').returns("KEYFORINFOSIGNED")
|
203
252
|
|
@@ -207,7 +256,7 @@ describe BrNfe::Base do
|
|
207
256
|
assinatura.remove_namespaces!
|
208
257
|
assinatura.xpath('Signature/Signature/Value').first.text.must_equal 'STUBADO'
|
209
258
|
assinatura.xpath('Signature/SignatureValue').first.text.must_equal 'KEYFORINFOSIGNED'
|
210
|
-
assinatura.xpath('Signature/KeyInfo/X509Data/X509Certificate').first.text.must_equal '
|
259
|
+
assinatura.xpath('Signature/KeyInfo/X509Data/X509Certificate').first.text.must_equal 'MCYwHAIBADAASDIHASDIASHDIAMAMGAQADAQAwAwYBAAMBAA=='
|
211
260
|
end
|
212
261
|
end
|
213
262
|
|
@@ -225,8 +274,13 @@ describe BrNfe::Base do
|
|
225
274
|
OpenSSL::PKCS12.expects(:new).never
|
226
275
|
subject.certificado.must_equal certificado
|
227
276
|
end
|
277
|
+
it "posso setar o certificado" do
|
278
|
+
subject.certificado = 'certificado 123'
|
279
|
+
subject.certificado.must_equal 'certificado 123'
|
280
|
+
end
|
228
281
|
end
|
229
282
|
|
283
|
+
|
230
284
|
describe "#client_wsdl" do
|
231
285
|
before do
|
232
286
|
# Stub metodos para configuração do client WSDL
|
@@ -4,6 +4,25 @@ require 'br_nfe/helper/have_address_test.rb'
|
|
4
4
|
describe BrNfe::Destinatario do
|
5
5
|
subject { FactoryGirl.build(:destinatario, endereco: endereco) }
|
6
6
|
let(:endereco) { FactoryGirl.build(:endereco) }
|
7
|
+
|
8
|
+
describe "validations" do
|
9
|
+
it { must validate_presence_of(:cpf_cnpj) }
|
10
|
+
it { must validate_presence_of(:razao_social) }
|
11
|
+
|
12
|
+
describe "valida o endereco" do
|
13
|
+
it "deve ser inválido se endereco for invalido" do
|
14
|
+
subject.endereco.stubs(:valid?).returns(false)
|
15
|
+
subject.endereco.stubs(:errors).returns(stub(full_messages: ["Erro 1"] ))
|
16
|
+
subject.valid?.must_equal false
|
17
|
+
subject.errors.full_messages.include?("Endereço: Erro 1").must_equal true
|
18
|
+
end
|
19
|
+
it "deve ser válido se endereco for valido" do
|
20
|
+
subject.endereco.stubs(:valid?).returns(true)
|
21
|
+
subject.valid?.must_equal true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
7
26
|
|
8
27
|
describe "#endereco" do
|
9
28
|
include BrNfeTest::HelperTest::HaveAddressTest
|
@@ -4,6 +4,26 @@ require 'br_nfe/helper/have_address_test.rb'
|
|
4
4
|
describe BrNfe::Emitente do
|
5
5
|
subject { FactoryGirl.build(:emitente, endereco: endereco) }
|
6
6
|
let(:endereco) { FactoryGirl.build(:endereco) }
|
7
|
+
|
8
|
+
describe "validations" do
|
9
|
+
it { must validate_presence_of(:inscricao_municipal) }
|
10
|
+
it { must validate_presence_of(:natureza_operacao) }
|
11
|
+
it { must validate_presence_of(:cnpj) }
|
12
|
+
it { must validate_presence_of(:razao_social) }
|
13
|
+
|
14
|
+
describe "valida o endereco" do
|
15
|
+
it "deve ser inválido se endereco for invalido" do
|
16
|
+
subject.endereco.stubs(:valid?).returns(false)
|
17
|
+
subject.endereco.stubs(:errors).returns(stub(full_messages: ["Erro 1"] ))
|
18
|
+
subject.valid?.must_equal false
|
19
|
+
subject.errors.full_messages.include?("Endereço: Erro 1").must_equal true
|
20
|
+
end
|
21
|
+
it "deve ser válido se endereco for valido" do
|
22
|
+
subject.endereco.stubs(:valid?).returns(true)
|
23
|
+
subject.valid?.must_equal true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
7
27
|
|
8
28
|
describe "#endereco" do
|
9
29
|
include BrNfeTest::HelperTest::HaveAddressTest
|
@@ -2,6 +2,15 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe BrNfe::Endereco do
|
4
4
|
subject { FactoryGirl.build(:endereco) }
|
5
|
+
|
6
|
+
describe "validations" do
|
7
|
+
it { must validate_presence_of(:logradouro) }
|
8
|
+
it { must validate_presence_of(:numero) }
|
9
|
+
it { must validate_presence_of(:bairro) }
|
10
|
+
it { must validate_presence_of(:codigo_municipio) }
|
11
|
+
it { must validate_presence_of(:uf) }
|
12
|
+
it { must validate_presence_of(:cep) }
|
13
|
+
end
|
5
14
|
|
6
15
|
describe "#default_values" do
|
7
16
|
it "for codigo_pais must equal to 1058 " do
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe BrNfe::Helper::CpfCnpj do
|
4
|
+
describe "when is a cnpj" do
|
5
|
+
subject { BrNfe::Helper::CpfCnpj.new('64.147.776/0001-11') }
|
6
|
+
|
7
|
+
it "#cpf?" do
|
8
|
+
subject.cpf?.must_equal false
|
9
|
+
end
|
10
|
+
|
11
|
+
it "#cnpj?" do
|
12
|
+
subject.cnpj?.must_equal true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "#cpf_ou_cnpj?" do
|
16
|
+
subject.cpf_ou_cnpj?.must_equal :cnpj
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#sem_formatacao" do
|
20
|
+
subject.sem_formatacao.must_equal '64147776000111'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "#com_formatacao" do
|
24
|
+
objeto = BrNfe::Helper::CpfCnpj.new('64147776000111')
|
25
|
+
subject.com_formatacao.must_equal '64.147.776/0001-11'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "#formatado_com_label" do
|
29
|
+
subject.formatado_com_label.must_equal 'CNPJ 64.147.776/0001-11'
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
describe "when is a cpf" do
|
34
|
+
subject { BrNfe::Helper::CpfCnpj.new('845.076.668-05') }
|
35
|
+
|
36
|
+
it "#cpf?" do
|
37
|
+
subject.cpf?.must_equal true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "#cnpj?" do
|
41
|
+
subject.cnpj?.must_equal false
|
42
|
+
end
|
43
|
+
|
44
|
+
it "#cpf_ou_cnpj?" do
|
45
|
+
subject.cpf_ou_cnpj?.must_equal :cpf
|
46
|
+
end
|
47
|
+
|
48
|
+
it "#sem_formatacao" do
|
49
|
+
subject.sem_formatacao.must_equal '84507666805'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "#com_formatacao" do
|
53
|
+
objeto = BrNfe::Helper::CpfCnpj.new('84507666805')
|
54
|
+
subject.com_formatacao.must_equal '845.076.668-05'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "#formatado_com_label" do
|
58
|
+
subject.formatado_com_label.must_equal 'CPF 845.076.668-05'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -2,6 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe BrNfe::Servico::Base do
|
4
4
|
subject { FactoryGirl.build(:br_nfe_servico_base) }
|
5
|
+
let(:rps) { FactoryGirl.build(:br_nfe_rps) }
|
5
6
|
|
6
7
|
describe "#lote_rps" do
|
7
8
|
it "deve inicializar como um vetor vazio" do
|
@@ -18,6 +19,33 @@ describe BrNfe::Servico::Base do
|
|
18
19
|
subject.lote_rps = {valor: '2'}
|
19
20
|
subject.lote_rps.must_equal [{valor: '2'}]
|
20
21
|
end
|
22
|
+
end
|
21
23
|
|
24
|
+
describe "#validar_lote_rps" do
|
25
|
+
it "se não houver nenhum rps, deve add um erro" do
|
26
|
+
subject.lote_rps = []
|
27
|
+
subject.errors.full_messages.must_equal( [] )
|
28
|
+
subject.send(:validar_lote_rps)
|
29
|
+
subject.errors.full_messages.must_equal( ["Deve conter ao menos 1 RPS"] )
|
30
|
+
end
|
31
|
+
context "deve validar o rps setando a opcao validar_recepcao_rps" do
|
32
|
+
before { subject.lote_rps = [rps] }
|
33
|
+
it "quando o rps for válido não deve setar nenhuma mensagem no objeto" do
|
34
|
+
rps.stubs(:errors).returns(stub(full_messages: ["Erro rps"]))
|
35
|
+
sequence_1 = sequence('sequence_1')
|
36
|
+
rps.expects(:validar_recepcao_rps=).with(true).in_sequence(sequence_1)
|
37
|
+
rps.expects(:invalid?).returns(false).in_sequence(sequence_1)
|
38
|
+
subject.send(:validar_lote_rps)
|
39
|
+
subject.errors.full_messages.must_equal( [] )
|
40
|
+
end
|
41
|
+
it "quando o rps for inválido deve setar mensagem de erro no objeto" do
|
42
|
+
rps.stubs(:errors).returns(stub(full_messages: ["Erro rps"]))
|
43
|
+
sequence_1 = sequence('sequence_1')
|
44
|
+
rps.expects(:validar_recepcao_rps=).with(true).in_sequence(sequence_1)
|
45
|
+
rps.expects(:invalid?).returns(true).in_sequence(sequence_1)
|
46
|
+
subject.send(:validar_lote_rps)
|
47
|
+
subject.errors.full_messages.must_equal( ["RPS 1: Erro rps"] )
|
48
|
+
end
|
49
|
+
end
|
22
50
|
end
|
23
51
|
end
|