br_nfe 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +15 -0
  3. data/Gemfile.lock +169 -0
  4. data/LICENSE +20 -0
  5. data/README.markdown +6 -0
  6. data/Rakefile +13 -0
  7. data/br_nfe.gemspec +28 -0
  8. data/lib/br_nfe/active_model_base.rb +62 -0
  9. data/lib/br_nfe/base.rb +168 -0
  10. data/lib/br_nfe/condicao_pagamento.rb +26 -0
  11. data/lib/br_nfe/destinatario.rb +26 -0
  12. data/lib/br_nfe/emitente.rb +40 -0
  13. data/lib/br_nfe/endereco.rb +44 -0
  14. data/lib/br_nfe/helper/cpf_cnpj.rb +60 -0
  15. data/lib/br_nfe/helper/have_address.rb +29 -0
  16. data/lib/br_nfe/helper/have_condicao_pagamento.rb +24 -0
  17. data/lib/br_nfe/helper/have_destinatario.rb +18 -0
  18. data/lib/br_nfe/helper/have_emitente.rb +20 -0
  19. data/lib/br_nfe/helper/have_intermediario.rb +24 -0
  20. data/lib/br_nfe/helper/have_rps.rb +27 -0
  21. data/lib/br_nfe/helper/string_methods.rb +21 -0
  22. data/lib/br_nfe/seed.rb +195 -0
  23. data/lib/br_nfe/servico/base.rb +35 -0
  24. data/lib/br_nfe/servico/betha/base.rb +74 -0
  25. data/lib/br_nfe/servico/betha/v1/build_response.rb +219 -0
  26. data/lib/br_nfe/servico/betha/v1/cancelamento_nfs.rb +52 -0
  27. data/lib/br_nfe/servico/betha/v1/consulta_lote_rps.rb +31 -0
  28. data/lib/br_nfe/servico/betha/v1/consulta_nfs_por_rps.rb +34 -0
  29. data/lib/br_nfe/servico/betha/v1/consulta_nfse.rb +50 -0
  30. data/lib/br_nfe/servico/betha/v1/consulta_situacao_lote_rps.rb +18 -0
  31. data/lib/br_nfe/servico/betha/v1/gateway.rb +115 -0
  32. data/lib/br_nfe/servico/betha/v1/recepcao_lote_rps.rb +89 -0
  33. data/lib/br_nfe/servico/betha/v2/cancelamento_nfs.rb +25 -0
  34. data/lib/br_nfe/servico/betha/v2/consulta_lote_rps.rb +27 -0
  35. data/lib/br_nfe/servico/betha/v2/consulta_nfse_por_rps.rb +27 -0
  36. data/lib/br_nfe/servico/betha/v2/envio_lote_rps_sincrono.rb +26 -0
  37. data/lib/br_nfe/servico/betha/v2/gateway.rb +198 -0
  38. data/lib/br_nfe/servico/betha/v2/gera_nfse.rb +25 -0
  39. data/lib/br_nfe/servico/betha/v2/recepcao_lote_rps.rb +47 -0
  40. data/lib/br_nfe/servico/betha/v2/response.rb +23 -0
  41. data/lib/br_nfe/servico/betha/v2/substituicao_nfse.rb +39 -0
  42. data/lib/br_nfe/servico/intermediario.rb +17 -0
  43. data/lib/br_nfe/servico/response/default.rb +34 -0
  44. data/lib/br_nfe/servico/response/nota_fiscal.rb +73 -0
  45. data/lib/br_nfe/servico/rps.rb +103 -0
  46. data/lib/br_nfe/version.rb +8 -0
  47. data/lib/br_nfe.rb +146 -0
  48. data/test/br_nfe/base_test.rb +274 -0
  49. data/test/br_nfe/condicao_pagamento_test.rb +23 -0
  50. data/test/br_nfe/destinatario_test.rb +26 -0
  51. data/test/br_nfe/emitente_test.rb +26 -0
  52. data/test/br_nfe/endereco_test.rb +50 -0
  53. data/test/br_nfe/helper/have_address_test.rb +62 -0
  54. data/test/br_nfe/helper/have_condicao_pagamento_test.rb +71 -0
  55. data/test/br_nfe/helper/have_destinatario_test.rb +64 -0
  56. data/test/br_nfe/helper/have_emitente_test.rb +63 -0
  57. data/test/br_nfe/helper/have_intermediario_test.rb +77 -0
  58. data/test/br_nfe/helper/have_rps_test.rb +59 -0
  59. data/test/br_nfe/servico/base_test.rb +23 -0
  60. data/test/br_nfe/servico/betha/base_test.rb +106 -0
  61. data/test/br_nfe/servico/betha/v1/build_response_test.rb +558 -0
  62. data/test/br_nfe/servico/betha/v1/cancelamento_nfs_test.rb +62 -0
  63. data/test/br_nfe/servico/betha/v1/consulta_lote_rps_test.rb +42 -0
  64. data/test/br_nfe/servico/betha/v1/consulta_nfs_por_rps_test.rb +68 -0
  65. data/test/br_nfe/servico/betha/v1/consulta_nfse_test.rb +57 -0
  66. data/test/br_nfe/servico/betha/v1/consulta_situacao_lote_rps_test.rb +27 -0
  67. data/test/br_nfe/servico/betha/v1/gateway_test.rb +174 -0
  68. data/test/br_nfe/servico/betha/v1/recepcao_lote_rps_test.rb +235 -0
  69. data/test/br_nfe/servico/response/default_test.rb +54 -0
  70. data/test/br_nfe/servico/response/nota_fiscal_test.rb +41 -0
  71. data/test/br_nfe/servico/rps_test.rb +214 -0
  72. data/test/certificado.rb +12 -0
  73. data/test/factories/base.rb +5 -0
  74. data/test/factories/condicao_pagamento.rb +10 -0
  75. data/test/factories/destinatario.rb +11 -0
  76. data/test/factories/emitente.rb +15 -0
  77. data/test/factories/endereco.rb +12 -0
  78. data/test/factories/servico/base.rb +5 -0
  79. data/test/factories/servico/betha/base.rb +5 -0
  80. data/test/factories/servico/betha/v1/build_response.rb +6 -0
  81. data/test/factories/servico/betha/v1/cancelamento_nfs.rb +7 -0
  82. data/test/factories/servico/betha/v1/consulta_lote_rps.rb +6 -0
  83. data/test/factories/servico/betha/v1/consulta_nfs_por_rps.rb +6 -0
  84. data/test/factories/servico/betha/v1/consulta_nfse.rb +8 -0
  85. data/test/factories/servico/betha/v1/consulta_situacao_lote_rps.rb +6 -0
  86. data/test/factories/servico/betha/v1/gateway.rb +5 -0
  87. data/test/factories/servico/betha/v1/recepcao_lote_rps.rb +6 -0
  88. data/test/factories/servico/intermediario.rb +7 -0
  89. data/test/factories/servico/response/default.rb +10 -0
  90. data/test/factories/servico/response/nota_fiscal.rb +47 -0
  91. data/test/factories/servico/rps.rb +44 -0
  92. data/test/test_helper.rb +39 -0
  93. metadata +263 -0
@@ -0,0 +1,198 @@
1
+ module BrNfe
2
+ module Servico
3
+ module Betha
4
+ module V2
5
+ class Gateway < BrNfe::Servico::Betha::Base
6
+
7
+ attr_accessor :numero_nfse
8
+ attr_accessor :codigo_cancelamento
9
+
10
+ def namespaces
11
+ {"xmlns:e" => "http://www.betha.com.br/e-nota-contribuinte-ws"}
12
+ end
13
+
14
+ def namespace_identifier
15
+ :e
16
+ end
17
+
18
+ def version
19
+ :v2
20
+ end
21
+
22
+ def wsdl
23
+ "http://e-gov.betha.com.br/e-nota-contribuinte-#{'test-' if env == :test}ws/nfseWS?wsdl"
24
+ end
25
+
26
+ def request
27
+ set_response( client_wsdl.call(method_wsdl, message: "#{cabecalho}#{content_xml}") )
28
+ rescue Savon::SOAPFault => error
29
+ return @response = BrNfe::Servico::Response::Default.new(success: false, error_messages: [error.message])
30
+ end
31
+
32
+ def set_response(resp)
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)
35
+ end
36
+
37
+ def cabecalho
38
+ Nokogiri::XML::Builder.new do
39
+ nfseCabecMsg do
40
+ cdata(Nokogiri::XML::Builder.new do |xml|
41
+ xml.cabecalho(xmlns: "http://www.betha.com.br/e-nota-contribuinte-ws", versao: "2.02"){
42
+ xml.versaoDados 2.02
43
+ }
44
+ end.doc.root)
45
+ end
46
+ end.doc.root.to_s.gsub(/\n/,'').gsub(/\t/,'')
47
+ end
48
+
49
+ def content_xml
50
+ Nokogiri::XML::Builder.new do
51
+ nfseDadosMsg do
52
+ cdata(xml_builder)
53
+ end
54
+ end.doc.root.to_s
55
+ end
56
+
57
+ private
58
+
59
+ def format_data_xml_for_signature(data_xml)
60
+ xml = Nokogiri::XML(data_xml.to_s, &:noblanks)
61
+ node_name = xml.root.node_name
62
+ xml = xml.root.xpath("//#{node_name}")
63
+ xml.attr("xmlns", "http://www.betha.com.br/e-nota-contribuinte-ws")
64
+ canonicalize xml.to_s
65
+ end
66
+
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)
73
+ }
74
+ xml.InscricaoMunicipal "#{intermediario.inscricao_municipal}".max_size(15) unless intermediario.inscricao_municipal.blank?
75
+ }
76
+ xml.RazaoSocial "#{intermediario.razao_social}".max_size(150)
77
+ }
78
+ end
79
+
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?
104
+ }
105
+
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
+ }
119
+ end
120
+
121
+ def xml_inf_declaracao_prestacao_servico(rps)
122
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
123
+ xml.InfDeclaracaoPrestacaoServico('Id' => "rps#{rps.numero}") {
124
+ xml.Rps {
125
+ tag_identificacao_rps(xml, rps)
126
+
127
+ xml.DataEmissao value_date(rps.data_emissao)
128
+ xml.Status "#{rps.status}".max_size(1)
129
+
130
+ tag_rps_substituido(xml, rps)
131
+ }
132
+
133
+ # Dia, mês e ano da prestação do serviço
134
+ # Quando houver RPS, a nota será gerada com base na <DataEmissao> do RPS, caso contrário utilizará a <Competencia>
135
+ xml.Competencia value_date(rps.competencia)
136
+
137
+ tag_dados_servico(xml, rps)
138
+
139
+ tag_prestador(xml)
140
+
141
+ tag_dados_tomador(xml, rps.destinatario)
142
+
143
+ tag_intermediario_servico(xml, rps.intermediario)
144
+
145
+ tag_dados_construcao_civil(xml, rps)
146
+
147
+ # 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?
149
+
150
+ xml.OptanteSimplesNacional value_true_false(emitente.optante_simples_nacional?) # (1)sim ----- (2)não
151
+ xml.IncentivoFiscal value_true_false(emitente.incentivo_fiscal?) # (1)sim ----- (2)não
152
+
153
+ }
154
+ end
155
+ end
156
+
157
+ def xml_rps_assinado(rps)
158
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
159
+ xml.Rps{
160
+ arps = xml_inf_declaracao_prestacao_servico(rps).doc.root
161
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( arps.to_s )
162
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( assinatura_xml( arps.to_s, "#rps#{rps.numero}" ) )
163
+ }
164
+ end
165
+ end
166
+
167
+ def xml_pedido_cancelamento_assinado
168
+ xml = Nokogiri::XML::Builder.new do |xml|
169
+ xml.Pedido {
170
+ inf_pedido_cancelamento = xml_inf_pedido_cancelamento.doc.root
171
+
172
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( inf_pedido_cancelamento.to_s )
173
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( assinatura_xml(inf_pedido_cancelamento.to_s, "#nf#{numero_nfse}") )
174
+ }
175
+ end
176
+ end
177
+
178
+ def xml_inf_pedido_cancelamento
179
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
180
+ xml.InfPedidoCancelamento(Id: "nf#{numero_nfse}"){
181
+ xml.IdentificacaoNfse{
182
+ xml.Numero BrNfe::Helper.only_number(numero_nfse).max_size(15)
183
+ xml.CpfCnpj{
184
+ tag_cpf_cnpj(xml, emitente.cnpj)
185
+ }
186
+ xml.InscricaoMunicipal emitente.inscricao_municipal.max_size(15) if !emitente.inscricao_municipal.blank? && env == :production
187
+ xml.CodigoMunicipio "#{emitente.endereco.codigo_municipio}".max_size(7)
188
+ }
189
+ xml.CodigoCancelamento "#{codigo_cancelamento}".max_size(4)
190
+ }
191
+ end
192
+ end
193
+
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,25 @@
1
+ module BrNfe
2
+ module Servico
3
+ module Betha
4
+ module V2
5
+ class GeraNfse < BrNfe::Servico::Betha::V2::Gateway
6
+ include BrNfe::Helper::HaveRps
7
+
8
+ def method_wsdl
9
+ :gerar_nfse
10
+ end
11
+
12
+ def xml_builder
13
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
14
+ xml.GerarNfseEnvio(xmlns: "http://www.betha.com.br/e-nota-contribuinte-ws") {
15
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_rps_assinado(rps).doc.root.to_s)
16
+ }
17
+ end.doc.root
18
+
19
+ canonicalize xml
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,47 @@
1
+ module BrNfe
2
+ module Servico
3
+ module Betha
4
+ module V2
5
+ class RecepcaoLoteRps < BrNfe::Servico::Betha::V2::Gateway
6
+ def method_wsdl
7
+ :recepcionar_lote_rps
8
+ end
9
+
10
+ def xml_builder
11
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
12
+ xml.EnviarLoteRpsEnvio(xmlns: "http://www.betha.com.br/e-nota-contribuinte-ws") {
13
+ xml_lote_rps = lote_rps_xml.doc.root
14
+
15
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_lote_rps.to_s )
16
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( assinatura_xml(xml_lote_rps.to_s, "#lote#{numero_lote_rps}") )
17
+ }
18
+ end.doc.root
19
+
20
+ canonicalize xml
21
+ end
22
+
23
+
24
+ def lote_rps_xml
25
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
26
+ xml.LoteRps("Id" => "lote#{numero_lote_rps}", versao: "2.02"){
27
+ xml.NumeroLote BrNfe::Helper.only_number(numero_lote_rps).max_size(15)
28
+ xml.CpfCnpj {
29
+ tag_cpf_cnpj(xml, emitente.cnpj)
30
+ }
31
+ # O Ambiente de homologação da Betha não aceita Inscrição Municipal (baita ambiente de homologação)
32
+ xml.InscricaoMunicipal emitente.inscricao_municipal.max_size(15) if !emitente.inscricao_municipal.blank? && env == :production
33
+
34
+ xml.QuantidadeRps lote_rps.size
35
+ xml.ListaRps {
36
+ lote_rps.each do |obj_rps|
37
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_rps_assinado(obj_rps).doc.root.to_s)
38
+ end
39
+ }
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,23 @@
1
+ module BrNfe
2
+ module Servico
3
+ module Betha
4
+ module V2
5
+ class Response < BrNfe::ActiveModelBase
6
+ attr_accessor :xml, :nfe_method
7
+
8
+ def messages
9
+ Nori.new(:convert_tags_to => lambda { |tag| tag.snakecase.to_sym }).parse(xml.to_s)["#{nfe_method.to_s}_resposta".to_sym]
10
+ end
11
+
12
+ def success?
13
+ raise "Não implementado"
14
+ end
15
+
16
+ def errors
17
+ raise "Não implementado"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ module BrNfe
2
+ module Servico
3
+ module Betha
4
+ module V2
5
+ class SubstituicaoNfse < BrNfe::Servico::Betha::V2::Gateway
6
+ include BrNfe::Helper::HaveRps
7
+
8
+ def method_wsdl
9
+ :substituir_nfse
10
+ end
11
+
12
+ def xml_builder
13
+ xml = Nokogiri::XML::Builder.new do |xml|
14
+ xml.SubstituirNfseEnvio(xmlns: "http://www.betha.com.br/e-nota-contribuinte-ws") {
15
+ xml_substituicao = xml_substituicao_nfse.doc.root
16
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_substituicao.to_s )
17
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( assinatura_xml(xml_substituicao.to_s, "#substituicao") )
18
+ }
19
+ end.doc.root
20
+
21
+ canonicalize xml
22
+ end
23
+
24
+
25
+ def xml_substituicao_nfse
26
+ Nokogiri::XML::Builder.new do |xml|
27
+ xml.SubstituicaoNfse(Id: "substituicao") {
28
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_pedido_cancelamento_assinado.doc.root.to_s )
29
+ xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_rps_assinado(rps).doc.root.to_s )
30
+ }
31
+ end
32
+ end
33
+
34
+
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,17 @@
1
+ module BrNfe
2
+ module Servico
3
+ class Intermediario < BrNfe::ActiveModelBase
4
+
5
+ attr_accessor :cpf_cnpj
6
+ attr_accessor :inscricao_municipal
7
+ attr_accessor :razao_social
8
+
9
+ validates :cpf_cnpj, :razao_social, presence: true
10
+
11
+ def razao_social
12
+ "#{@razao_social}".to_valid_format_nf
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ module BrNfe
2
+ module Servico
3
+ module Response
4
+ class Default < BrNfe::ActiveModelBase
5
+ attr_accessor :success
6
+ attr_accessor :error_messages
7
+ attr_accessor :notas_fiscais
8
+
9
+ attr_accessor :protocolo
10
+ attr_accessor :data_recebimento
11
+ attr_accessor :numero_lote
12
+
13
+
14
+ def initialize(attributes = {})
15
+ self.notas_fiscais = [] # Para poder utilizar o <<
16
+ self.error_messages = [] # Para poder utilizar o <<
17
+ super
18
+ end
19
+
20
+ def notas_fiscais
21
+ @notas_fiscais = [@notas_fiscais].flatten # Para retornar sempre um vetor
22
+ end
23
+
24
+ def error_messages
25
+ @error_messages = [@error_messages].flatten
26
+ end
27
+
28
+ def success?
29
+ success
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,73 @@
1
+ module BrNfe
2
+ module Servico
3
+ module Response
4
+ class NotaFiscal < BrNfe::ActiveModelBase
5
+ include BrNfe::Helper::HaveIntermediario
6
+ include BrNfe::Helper::HaveDestinatario
7
+ include BrNfe::Helper::HaveEmitente
8
+ include BrNfe::Helper::HaveCondicaoPagamento
9
+
10
+ attr_accessor :numero_nf
11
+ attr_accessor :codigo_verificacao
12
+ attr_accessor :data_emissao
13
+ attr_accessor :url_nf
14
+
15
+ #identificacao do rps
16
+ attr_accessor :rps_numero
17
+ attr_accessor :rps_serie
18
+ attr_accessor :rps_tipo
19
+ attr_accessor :rps_situacao
20
+
21
+ attr_accessor :data_emissao_rps # Datetime
22
+ attr_accessor :competencia #DateTime
23
+ attr_accessor :outras_informacoes
24
+
25
+ # dados dos serviços
26
+ attr_accessor :item_lista_servico
27
+ attr_accessor :codigo_cnae
28
+ attr_accessor :discriminacao
29
+ attr_accessor :codigo_municipio
30
+
31
+ #Valores dos serviços
32
+ attr_accessor :valor_servicos
33
+ attr_accessor :valor_deducoes
34
+ attr_accessor :valor_pis
35
+ attr_accessor :valor_cofins
36
+ attr_accessor :valor_inss
37
+ attr_accessor :valor_ir
38
+ attr_accessor :valor_csll
39
+ attr_accessor :iss_retido
40
+ attr_accessor :valor_iss
41
+ attr_accessor :base_calculo
42
+ attr_accessor :aliquota
43
+ attr_accessor :desconto_condicionado
44
+ attr_accessor :desconto_incondicionado
45
+
46
+ # Orgão gerador
47
+ attr_accessor :orgao_gerador_municipio
48
+ attr_accessor :orgao_gerador_uf
49
+
50
+ # Dados de cancelamento da NF
51
+ attr_accessor :cancelamento_codigo
52
+ attr_accessor :cancelamento_numero_nf
53
+ attr_accessor :cancelamento_cnpj
54
+ attr_accessor :cancelamento_inscricao_municipal
55
+ attr_accessor :cancelamento_municipio
56
+ attr_accessor :cancelamento_sucesso
57
+ attr_accessor :cancelamento_data_hora
58
+
59
+ # Se a NF foi substituida
60
+ attr_accessor :nfe_substituidora
61
+ def substituida?
62
+ !nfe_substituidora.blank?
63
+ end
64
+
65
+ # dados de construcao civil
66
+ attr_accessor :codigo_obra
67
+ attr_accessor :codigo_art
68
+
69
+
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,103 @@
1
+ module BrNfe
2
+ module Servico
3
+ class Rps < BrNfe::ActiveModelBase
4
+ include BrNfe::Helper::HaveDestinatario
5
+ include BrNfe::Helper::HaveIntermediario
6
+ include BrNfe::Helper::HaveCondicaoPagamento
7
+
8
+ attr_accessor :validar_recepcao_rps
9
+
10
+ # Sempre que houver RPS, essas informações são obrigatórias
11
+ validates :numero, :serie, :tipo, presence: true
12
+
13
+ with_options if: :validar_recepcao_rps do |record|
14
+ record.validates :data_emissao, :item_lista_servico, :discriminacao, :codigo_municipio,
15
+ :valor_servicos, :base_calculo, presence: true
16
+ record.validates :valor_iss, :aliquota, presence: true, unless: :iss_retido?
17
+
18
+ record.validates :valor_servicos, :valor_deducoes, :valor_pis, :valor_cofins, :valor_inss, :valor_ir,
19
+ :valor_csll, :outras_retencoes, :valor_iss, :aliquota, :base_calculo,
20
+ :desconto_incondicionado, :desconto_condicionado, numericality: true, allow_blank: true
21
+
22
+ record.validate :validar_intermediario
23
+ record.validate :validar_destinatario
24
+ end
25
+
26
+ attr_accessor :numero
27
+ attr_accessor :serie
28
+ attr_accessor :tipo
29
+
30
+ attr_accessor :data_emissao
31
+ attr_accessor :status
32
+ attr_accessor :competencia
33
+
34
+ attr_accessor :numero_substituicao
35
+ attr_accessor :serie_substituicao
36
+ attr_accessor :tipo_substituicao
37
+
38
+ #Para construção civil
39
+ attr_accessor :codigo_obra
40
+ attr_accessor :codigo_art
41
+
42
+ attr_accessor :valor_servicos
43
+ attr_accessor :valor_deducoes
44
+ attr_accessor :valor_pis
45
+ attr_accessor :valor_cofins
46
+ attr_accessor :valor_inss
47
+ attr_accessor :valor_ir
48
+ attr_accessor :valor_csll
49
+ attr_accessor :outras_retencoes
50
+ attr_accessor :iss_retido
51
+ attr_accessor :valor_iss
52
+ attr_accessor :aliquota
53
+ attr_accessor :base_calculo
54
+ attr_accessor :desconto_incondicionado
55
+ attr_accessor :desconto_condicionado
56
+
57
+ attr_accessor :responsavel_retencao
58
+ attr_accessor :item_lista_servico
59
+ attr_accessor :codigo_tributacao_municipio
60
+ attr_accessor :discriminacao
61
+ attr_accessor :exigibilidade_iss
62
+ attr_accessor :codigo_municipio
63
+ attr_accessor :municipio_incidencia
64
+ attr_accessor :codigo_pais
65
+ attr_accessor :numero_processo
66
+ attr_accessor :codigo_cnae
67
+ attr_accessor :outras_informacoes
68
+
69
+ def contem_substituicao?
70
+ numero_substituicao.present? && serie_substituicao.present? && tipo_substituicao.present?
71
+ end
72
+
73
+ def iss_retido?
74
+ BrNfe.true_values.include?(iss_retido)
75
+ end
76
+
77
+ def competencia
78
+ @competencia || data_emissao
79
+ end
80
+
81
+ def default_values
82
+ {
83
+ codigo_pais: '1058',
84
+ validar_recepcao_rps: false
85
+ }
86
+ end
87
+ private
88
+
89
+ def validar_intermediario
90
+ return true unless intermediario
91
+ if intermediario.invalid?
92
+ intermediario.errors.full_messages.map{|msg| errors.add(:intermediario, msg) }
93
+ end
94
+ end
95
+
96
+ def validar_destinatario
97
+ if destinatario.invalid?
98
+ destinatario.errors.full_messages.map{|msg| errors.add(:destinatario, msg) }
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,8 @@
1
+ module BrNfe
2
+ module Version
3
+ MAJOR = 1 #inclui alterações de API e pode quebrar compatibilidade com versões anteriores
4
+ MINOR = 0 #inclui novas funcionalidades, sem quebrar APIs existentes
5
+ PATCH = 0 #corrige bugs ou traz melhorias em implementações já existentes
6
+ CURRENT = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
+ end
8
+ end