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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -1
  3. data/README.markdown +263 -1
  4. data/br_nfe.gemspec +14 -5
  5. data/lib/br_nfe/base.rb +6 -1
  6. data/lib/br_nfe/helper/cpf_cnpj.rb +0 -5
  7. data/lib/br_nfe/helper/have_address.rb +1 -5
  8. data/lib/br_nfe/helper/have_rps.rb +7 -0
  9. data/lib/br_nfe/servico/betha/base.rb +52 -41
  10. data/lib/br_nfe/servico/betha/build_response.rb +141 -0
  11. data/lib/br_nfe/servico/betha/v1/build_response.rb +4 -102
  12. data/lib/br_nfe/servico/betha/v1/consulta_lote_rps.rb +3 -1
  13. data/lib/br_nfe/servico/betha/v1/consulta_nfs_por_rps.rb +5 -2
  14. data/lib/br_nfe/servico/betha/v1/consulta_nfse.rb +2 -1
  15. data/lib/br_nfe/servico/betha/v1/gateway.rb +66 -56
  16. data/lib/br_nfe/servico/betha/v1/recepcao_lote_rps.rb +16 -8
  17. data/lib/br_nfe/servico/betha/v2/build_response.rb +159 -0
  18. data/lib/br_nfe/servico/betha/v2/cancelamento_nfs.rb +8 -3
  19. data/lib/br_nfe/servico/betha/v2/consulta_lote_rps.rb +7 -4
  20. data/lib/br_nfe/servico/betha/v2/consulta_nfse_por_rps.rb +5 -5
  21. data/lib/br_nfe/servico/betha/v2/envio_lote_rps_sincrono.rb +7 -3
  22. data/lib/br_nfe/servico/betha/v2/gateway.rb +79 -56
  23. data/lib/br_nfe/servico/betha/v2/gera_nfse.rb +8 -3
  24. data/lib/br_nfe/servico/betha/v2/recepcao_lote_rps.rb +9 -4
  25. data/lib/br_nfe/servico/betha/v2/substituicao_nfse.rb +8 -4
  26. data/lib/br_nfe/servico/response/nota_fiscal.rb +13 -4
  27. data/lib/br_nfe/servico/rps.rb +2 -2
  28. data/lib/br_nfe/version.rb +1 -1
  29. data/lib/br_nfe.rb +2 -1
  30. data/test/br_nfe/base_test.rb +55 -1
  31. data/test/br_nfe/destinatario_test.rb +19 -0
  32. data/test/br_nfe/emitente_test.rb +20 -0
  33. data/test/br_nfe/endereco_test.rb +9 -0
  34. data/test/br_nfe/helper/cpf_cnpj_test.rb +61 -0
  35. data/test/br_nfe/servico/base_test.rb +28 -0
  36. data/test/br_nfe/servico/betha/base_test.rb +61 -32
  37. data/test/br_nfe/servico/betha/v1/build_response_test.rb +6 -7
  38. data/test/br_nfe/servico/betha/v1/cancelamento_nfs_test.rb +6 -0
  39. data/test/br_nfe/servico/betha/v1/consulta_lote_rps_test.rb +4 -0
  40. data/test/br_nfe/servico/betha/v1/consulta_nfse_test.rb +17 -0
  41. data/test/br_nfe/servico/betha/v1/gateway_test.rb +17 -40
  42. data/test/br_nfe/servico/betha/v1/recepcao_lote_rps_test.rb +12 -2
  43. data/test/br_nfe/servico/betha/v2/cancelamento_nfs_test.rb +40 -0
  44. data/test/br_nfe/servico/betha/v2/consulta_lote_rps_test.rb +38 -0
  45. data/test/br_nfe/servico/betha/v2/consulta_nfse_por_rps_test.rb +36 -0
  46. data/test/br_nfe/servico/betha/v2/envio_lote_rps_sincrono_test.rb +46 -0
  47. data/test/br_nfe/servico/betha/v2/gateway_test.rb +372 -0
  48. data/test/br_nfe/servico/betha/v2/gera_nfse_test.rb +58 -0
  49. data/test/br_nfe/servico/betha/v2/recepcao_lote_rps_test.rb +103 -0
  50. data/test/br_nfe/servico/betha/v2/substituicao_nfse_test.rb +80 -0
  51. data/test/br_nfe/servico/intermediario_test.rb +16 -0
  52. data/test/br_nfe/servico/rps_test.rb +141 -0
  53. data/test/factories/servico/betha/v1/gateway.rb +1 -1
  54. data/test/factories/servico/betha/v2/cancelamento_nfs.rb +7 -0
  55. data/test/factories/servico/betha/v2/consulta_lote_rps.rb +6 -0
  56. data/test/factories/servico/betha/v2/consulta_nfse_por_rps.rb +6 -0
  57. data/test/factories/servico/betha/v2/envio_lote_rps_sincrono.rb +5 -0
  58. data/test/factories/servico/betha/v2/gateway.rb +5 -0
  59. data/test/factories/servico/betha/v2/gera_nfse.rb +6 -0
  60. data/test/factories/servico/betha/v2/recepcao_lote_rps.rb +5 -0
  61. data/test/factories/servico/betha/v2/substituicao_nfse.rb +8 -0
  62. metadata +50 -17
  63. data/Gemfile +0 -15
  64. data/Rakefile +0 -13
  65. data/lib/br_nfe/seed.rb +0 -195
  66. data/lib/br_nfe/servico/betha/v2/response.rb +0 -23
  67. data/test/certificado.rb +0 -12
  68. 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
- @response = BrNfe::Servico::Betha::V2::Response.new(xml: resp.hash[:envelope][:body][method_response][:return], nfe_method: method_wsdl)
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(xml_builder)
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 tag_intermediario_servico(xml, intermediario)
68
- return unless intermediario
69
- xml.Intermediario{
70
- xml.IdentificacaoIntermediario{
71
- xml.CpfCnpj{
72
- tag_cpf_cnpj(xml, intermediario.cpf_cnpj)
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.InscricaoMunicipal "#{intermediario.inscricao_municipal}".max_size(15) unless intermediario.inscricao_municipal.blank?
87
+ xml.RazaoSocial "#{intermediario.razao_social}".max_size(150)
75
88
  }
76
- xml.RazaoSocial "#{intermediario.razao_social}".max_size(150)
77
- }
89
+ end
78
90
  end
79
91
 
80
- def tag_prestador(xml)
81
- xml.Prestador{
82
- xml.CpfCnpj{
83
- tag_cpf_cnpj(xml, emitente.cnpj)
84
- }
85
- xml.InscricaoMunicipal "#{emitente.inscricao_municipal}".max_size(15) if !emitente.inscricao_municipal.blank? && env == :production
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
- xml.IssRetido value_true_false(rps.iss_retido?)
107
- xml.ResponsavelRetencao "#{rps.responsavel_retencao}".max_size(1) unless rps.responsavel_retencao.blank?
108
- xml.ItemListaServico BrNfe::Helper.only_number(rps.item_lista_servico).rjust(4,'0').max_size(5)
109
- xml.CodigoCnae BrNfe::Helper.only_number(rps.codigo_cnae).max_size(7) unless rps.codigo_cnae.blank?
110
- xml.CodigoTributacaoMunicipio "#{rps.codigo_tributacao_municipio}".max_size(20) unless rps.codigo_tributacao_municipio.blank?
111
- xml.Discriminacao "#{rps.discriminacao}".max_size(2_000).remove_accents
112
- xml.CodigoMunicipio "#{rps.codigo_municipio}".max_size(7)
113
- # Não posso enviar o CodigoPais se a exigibilidade_iss não for 4 (exportação) - by bethagambis.com
114
- xml.CodigoPais rps.codigo_pais.max_size(4) if !rps.codigo_pais.blank? && rps.exigibilidade_iss == '4'
115
- xml.ExigibilidadeISS "#{rps.exigibilidade_iss}".max_size(2)
116
- xml.MunicipioIncidencia rps.municipio_incidencia.max_size(4) unless rps.municipio_incidencia.blank?
117
- xml.NumeroProcesso rps.numero_processo.max_size(30) unless rps.numero_processo.blank?
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
- tag_identificacao_rps(xml, rps)
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
- tag_rps_substituido(xml, rps)
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
- tag_dados_servico(xml, rps)
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
- tag_prestador(xml)
158
+ # Pestador / Emitente
159
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_prestador.doc.root.to_s )
140
160
 
141
- tag_dados_tomador(xml, rps.destinatario)
161
+ # Tomador / Destinatário
162
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_dados_tomador(rps.destinatario).doc.root.to_s )
142
163
 
143
- tag_intermediario_servico(xml, rps.intermediario)
164
+ # Intermediario
165
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_intermediario_servico(rps.intermediario).doc.root.to_s )
144
166
 
145
- tag_dados_construcao_civil(xml, rps)
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.doc.root
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.doc.root
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.doc.root
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 # Datetime
22
- attr_accessor :competencia #DateTime
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 :desconto_condicionado
44
- attr_accessor :desconto_incondicionado
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
@@ -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(:intermediario, msg) }
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(:destinatario, msg) }
98
+ destinatario.errors.full_messages.map{|msg| errors.add(:base, "Destinatário: #{msg}") }
99
99
  end
100
100
  end
101
101
  end
@@ -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 = 0 #corrige bugs ou traz melhorias em implementações já existentes
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 :Response
76
+ autoload :BuildResponse
76
77
  autoload :CancelamentoNfs
77
78
  autoload :ConsultaNfsePorRps
78
79
  autoload :EnvioLoteRpsSincrono
@@ -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 'MCYwHAIBADADBgEAMAAwBB8AHwAwADAIMAMGAQADAQAwAwYBAAMBAA=='
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