br_nfe 1.0.0 → 1.0.1
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/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
|