rnfse 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +7 -6
  4. data/lib/provedores.yml +8 -0
  5. data/lib/rnfse.rb +5 -1
  6. data/lib/rnfse/api.rb +44 -22
  7. data/lib/rnfse/api/abrasf_1_0.rb +100 -17
  8. data/lib/rnfse/api/abrasf_1_0/#definitions.json# +413 -0
  9. data/lib/rnfse/api/abrasf_1_0/cancelar_nfse.json +13 -0
  10. data/lib/rnfse/api/abrasf_1_0/consultar_nfse.json +17 -0
  11. data/lib/rnfse/api/abrasf_1_0/consultar_nfse_por_rps.json +13 -0
  12. data/lib/rnfse/api/abrasf_1_0/definitions.json +27 -3
  13. data/lib/rnfse/api/abrasf_1_0/recepcionar_lote_rps.json +1 -1
  14. data/lib/rnfse/api/iss_net_1_0.rb +46 -2
  15. data/lib/rnfse/api/speed_gov_1_0.rb +115 -0
  16. data/lib/rnfse/call_chain.rb +4 -4
  17. data/lib/rnfse/error.rb +15 -0
  18. data/lib/rnfse/hash.rb +24 -11
  19. data/lib/rnfse/string.rb +16 -2
  20. data/lib/rnfse/version.rb +1 -1
  21. data/lib/rnfse/xml_builder/abrasf_1_0.rb +103 -13
  22. data/lib/rnfse/xml_builder/iss_net_1_0.rb +34 -4
  23. data/lib/rnfse/xml_builder/speed_gov_1_0.rb +158 -0
  24. data/spec/api/abrasf_1_0/cancelar_nfse_json_spec.rb +25 -0
  25. data/spec/api/abrasf_1_0/consultar_lote_rps_json_spec.rb +23 -0
  26. data/spec/api/abrasf_1_0/consultar_nfse_json_spec.rb +45 -0
  27. data/spec/api/abrasf_1_0/consultar_nfse_por_rps_json_spec.rb +23 -0
  28. data/spec/api/abrasf_1_0/consultar_situacao_lote_rps_json_spec.rb +23 -0
  29. data/spec/api/abrasf_1_0_spec.rb +185 -6
  30. data/spec/api/iss_net_1_0_spec.rb +89 -9
  31. data/spec/api/speed_gov_1_0_spec.rb +243 -0
  32. data/spec/api_spec.rb +43 -28
  33. data/spec/error_spec.rb +10 -0
  34. data/spec/fixtures/abrasf_1_0/cancelar_nfse_envio.xml +16 -0
  35. data/spec/fixtures/abrasf_1_0/consultar_nfse.xml +23 -0
  36. data/spec/fixtures/abrasf_1_0/consultar_nfse_por_rps.xml +14 -0
  37. data/spec/fixtures/iss_net_1_0/cancelar_nfse_envio.xml +17 -0
  38. data/spec/fixtures/iss_net_1_0/consultar_nfse.xml +29 -0
  39. data/spec/fixtures/iss_net_1_0/consultar_nfse_por_rps.xml +17 -0
  40. data/spec/fixtures/speed_gov_1_0/consultar_nfse_envio.xml +29 -0
  41. data/spec/fixtures/speed_gov_1_0/consultar_nfse_rps_envio.xml +16 -0
  42. data/spec/fixtures/speed_gov_1_0/consultar_situacao_lote_rps_envio.xml +12 -0
  43. data/spec/fixtures/speed_gov_1_0/enviar_lote_rps_envio.xml +82 -0
  44. data/spec/fixtures/speed_gov_1_0/header.xml +9 -0
  45. data/spec/fixtures/vcr_cassettes/iss_net_1_0_cancelar_nfse.yml +107 -0
  46. data/spec/fixtures/vcr_cassettes/iss_net_1_0_consultar_nfse.yml +7937 -0
  47. data/spec/fixtures/vcr_cassettes/iss_net_1_0_consultar_nfse_por_rps.yml +242 -0
  48. data/spec/fixtures/vcr_cassettes/speed_gov_1_0_consultar_nfse.yml +60 -0
  49. data/spec/fixtures/vcr_cassettes/speed_gov_1_0_consultar_nfse_por_rps.yml +80 -0
  50. data/spec/fixtures/vcr_cassettes/speed_gov_1_0_consultar_situacao_lote_rps.yml +77 -0
  51. data/spec/fixtures/vcr_cassettes/speed_gov_1_0_recepcionar_lote_rps.yml +171 -0
  52. data/spec/fixtures/vcr_cassettes/speed_gov_1_0_recepcionar_lote_rps_ascii.yml +171 -0
  53. data/spec/hash_spec.rb +21 -0
  54. data/spec/spec_helper.rb +2 -0
  55. data/spec/string_spec.rb +31 -5
  56. data/spec/xml_builder/abrasf_1_0_spec.rb +110 -43
  57. data/spec/xml_builder/iss_net_1_0_spec.rb +111 -44
  58. data/spec/xml_builder/speed_gov_1_0_spec.rb +173 -0
  59. metadata +86 -37
  60. data/.gitignore +0 -25
  61. data/.rspec +0 -1
  62. data/.travis.yml +0 -14
  63. data/Gemfile +0 -3
  64. data/Guardfile +0 -15
  65. data/Procfile +0 -1
  66. data/Rakefile +0 -12
  67. data/rnfse.gemspec +0 -61
  68. data/spec/fixtures/abrasf_1_0/teste.xml +0 -8
  69. data/spec/support/.keep +0 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Cancelamento de NFS-e",
4
+ "description": "Esse serviço permite o cancelamento direto de uma NFS-e sem substituição da mesma por outra.",
5
+
6
+ "type": "object",
7
+ "properties": {
8
+ "identificacaoNfse": { "$ref": "definitions.json#/identificacaoNfse"},
9
+ "codigoCancelamento": { "$ref": "definitions.json#/codigoCancelamentoNfse"}
10
+ },
11
+ "required": ["identificacaoNfse", "codigoCancelamento"],
12
+ "additionalProperties": false
13
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Consulta de NFS-e",
4
+ "description": "Esse serviço permite a obtenção de determinada NFS-e já gerada.",
5
+
6
+ "type": "object",
7
+ "properties": {
8
+ "prestador": { "$ref": "definitions.json#/identificacaoPrestador" },
9
+ "numeroNfse": { "$ref": "definitions.json#/numeroNfse" },
10
+ "dataInicial": { "$ref": "definitions.json#/data" },
11
+ "dataFinal": { "$ref": "definitions.json#/data" },
12
+ "tomador": { "$ref": "definitions.json#/identificacaoTomador" },
13
+ "intermediarioServico": { "$ref": "definitions.json#/identificacaoIntermediarioServico" }
14
+ },
15
+ "required": ["prestador"],
16
+ "additionalProperties": false
17
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Consulta de NFS-e por RPS",
4
+ "description": "Esse serviço efetua a consulta de uma NFS-e a partir do número de RPS que a gerou.",
5
+
6
+ "type": "object",
7
+ "properties": {
8
+ "identificacaoRps": { "$ref": "definitions.json#/identificacaoRps" },
9
+ "prestador": { "$ref": "definitions.json#/identificacaoPrestador" }
10
+ },
11
+ "required": ["identificacaoRps", "prestador"],
12
+ "additionalProperties": false
13
+ }
@@ -2,7 +2,7 @@
2
2
  "numeroNfse": {
3
3
  "description": "Número da Nota Fiscal de Serviço Eletrônica, formado pelo ano com 04 (quatro) dígitos e um número seqüencial com 11 posições – Formato AAAANNNNNNNNNNN.",
4
4
  "type": "integer",
5
- "minimum": 199000000000000,
5
+ "minimum": 190000000000000,
6
6
  "maximum": 220099999999999
7
7
  },
8
8
  "codigoVerificacao": {
@@ -46,7 +46,7 @@
46
46
  "numeroRps": {
47
47
  "description": "Número do RPS",
48
48
  "type": "integer",
49
- "minimum": 1,
49
+ "minimum": 0,
50
50
  "maximum": 999999999999999
51
51
  },
52
52
  "serieRps": {
@@ -369,7 +369,9 @@
369
369
  {
370
370
  "type": "object",
371
371
  "properties": {
372
- "cpf": { "$ref": "#/cpf" }
372
+ "razaoSocial": { "$ref": "#/razaoSocial" },
373
+ "cpf": { "$ref": "#/cpf" },
374
+ "inscricaoMunicipal": { "$ref": "#/inscricaoMunicipal" }
373
375
  },
374
376
  "required": ["cpf"],
375
377
  "additionalProperties": false
@@ -385,5 +387,27 @@
385
387
  },
386
388
  "required": [],
387
389
  "additionalProperties": false
390
+ },
391
+ "data": {
392
+ "description": "Data como representada no padrão RFC 3339 section 5.6",
393
+ "type": "string",
394
+ "format": "date-time"
395
+ },
396
+ "codigoCancelamentoNfse": {
397
+ "description": "Código de cancelamento com base na tabela de erros e alertas",
398
+ "type": "string",
399
+ "maxLength": 4
400
+ },
401
+ "identificacaoNfse": {
402
+ "description": "Representa dados que identificam uma Nota Fiscal de Serviços Eletrônica",
403
+ "type": "object",
404
+ "properties": {
405
+ "numero": { "$ref": "#/numeroNfse" },
406
+ "cnpj": { "$ref": "#/cnpj" },
407
+ "inscricaoMunicipal": { "$ref": "#/inscricaoMunicipal" },
408
+ "codigoMunicipio": { "$ref": "#/codigoMunicipioIbge" }
409
+ },
410
+ "required": ["numero", "cnpj"],
411
+ "additionalProperties": false
388
412
  }
389
413
  }
@@ -18,7 +18,7 @@
18
18
  "type": "object",
19
19
  "properties": {
20
20
  "identificacaoRps": { "$ref": "definitions.json#/identificacaoRps" },
21
- "dataEmissao": { "type": "string", "format": "date-time" },
21
+ "dataEmissao": { "$ref": "definitions.json#/data" },
22
22
  "naturezaOperacao": { "$ref": "definitions.json#/naturezaOperacao" },
23
23
  "regimeEspecialTributacao": { "$ref": "definitions.json#/regimeEspecialTributacao" },
24
24
  "optanteSimplesNacional": { "type": "boolean" },
@@ -1,11 +1,32 @@
1
1
  # -*- coding: utf-8 -*-
2
- require 'json-schema'
3
2
 
4
3
  module Rnfse::API::IssNet10
5
4
  include Rnfse::API::Abrasf10
6
5
 
6
+ def operations()
7
+ [
8
+ :recepcionar_lote_rps, :consultar_situacao_lote_rps,
9
+ :consultar_nfse_por_rps, :consultar_nfse, :consultar_lote_rps,
10
+ :cancelar_nfse, :consultar_url_visualizacao_nfse,
11
+ :consultar_url_visualizacao_nfse_serie
12
+ ]
13
+ end
14
+
15
+ # def recepcionar_lote_rps(hash = {})
16
+ # validate_sign_options
17
+ # validate_options(hash)
18
+ # xml = xml_builder.build_recepcionar_lote_rps_xml(hash)
19
+ # xml.sign!(certificate: File.read(self.certificate), key: File.read(self.key))
20
+ # response = self.soap_client.call(
21
+ # :recepcionar_lote_rps,
22
+ # soap_action: 'RecepcionarLoteRps',
23
+ # message_tag: 'RecepcionarLoteRps',
24
+ # message: { :'xml!' => "<![CDATA[#{xml}]]>" })
25
+ # parse_response(response)
26
+ # end
27
+
7
28
  def consultar_situacao_lote_rps(hash = {})
8
- validate(hash)
29
+ validate_options(hash)
9
30
  xml = xml_builder.build_consultar_situacao_lote_rps_xml(hash)
10
31
  response = self.soap_client.call(
11
32
  :consultar_situacao_lote_rps,
@@ -15,4 +36,27 @@ module Rnfse::API::IssNet10
15
36
  parse_response(response)
16
37
  end
17
38
 
39
+ def consultar_nfse_por_rps(hash = {})
40
+ validate_options(hash)
41
+ xml = xml_builder.build_consultar_nfse_por_rps_xml(hash)
42
+ response = self.soap_client.call(
43
+ :consultar_nfse_por_rps,
44
+ soap_action: 'ConsultarNFSePorRPS',
45
+ message_tag: 'ConsultarNFSePorRPS',
46
+ message: { :'xml!' => "<![CDATA[#{xml}]]>" })
47
+ parse_response(response)
48
+ end
49
+
50
+ def consultar_url_visualizacao_nfse(hash = {})
51
+ raise Rnfse::Error::NotImplemented
52
+ end
53
+
54
+ def consultar_url_visualizacao_nfse_serie(hash = {})
55
+ raise Rnfse::Error::NotImplemented
56
+ end
57
+
58
+ def json_folder
59
+ 'iss_net_1_0'
60
+ end
61
+
18
62
  end
@@ -0,0 +1,115 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Rnfse::API::SpeedGov10
4
+ include Rnfse::API::Abrasf10
5
+
6
+ def recepcionar_lote_rps(hash = {})
7
+ validate_sign_options
8
+ validate_options(hash)
9
+ validate_ascii(hash)
10
+ header = xml_builder.build_header_xml()
11
+ parameters = xml_builder.build_recepcionar_lote_rps_xml(hash)
12
+ parameters.sign!(certificate: File.read(self.certificate), key: File.read(self.key))
13
+ response = self.soap_client.call(
14
+ :recepcionar_lote_rps,
15
+ soap_action: 'RecepcionarLoteRps',
16
+ message_tag: 'nfse:RecepcionarLoteRps',
17
+ message: { :'header!' => "<![CDATA[#{header}]]>",
18
+ :'parameters!' => "<![CDATA[#{parameters}]]>" })
19
+ parse_response(response)
20
+ end
21
+
22
+ def consultar_situacao_lote_rps(hash = {})
23
+ validate_options(hash)
24
+ header = xml_builder.build_header_xml()
25
+ parameters = xml_builder.build_consultar_situacao_lote_rps_envio_xml(hash)
26
+ response = self.soap_client.call(
27
+ :consultar_situacao_lote_rps,
28
+ soap_action: 'ConsultarSituacaoLoteRps',
29
+ message_tag: 'nfse:ConsultarSituacaoLoteRps',
30
+ message: { :'header!' => "<![CDATA[#{header}]]>",
31
+ :'parameters!' => "<![CDATA[#{parameters}]]>" })
32
+ parse_response(response)
33
+ end
34
+
35
+ def consultar_lote_rps(hash = {})
36
+ raise Rnfse::Error::NotImplemented
37
+ end
38
+
39
+ def consultar_nfse_por_rps(hash = {})
40
+ validate_options(hash)
41
+ validate_ascii(hash)
42
+ header = xml_builder.build_header_xml()
43
+ parameters = xml_builder.build_consultar_nfse_rps_envio_xml(hash)
44
+ response = self.soap_client.call(
45
+ :consultar_nfse_por_rps,
46
+ soap_action: 'ConsultarNfsePorRps',
47
+ message_tag: 'nfse:ConsultarNfsePorRps',
48
+ message: { :'header!' => "<![CDATA[#{header}]]>",
49
+ :'parameters!' => "<![CDATA[#{parameters}]]>" })
50
+ parse_response(response)
51
+ end
52
+
53
+ def consultar_nfse(hash = {})
54
+ validate_options(hash)
55
+ header = xml_builder.build_header_xml()
56
+ parameters = xml_builder.build_consultar_nfse_envio_xml(hash)
57
+ response = self.soap_client.call(
58
+ :consultar_situacao_lote_rps,
59
+ soap_action: 'ConsultarNfse',
60
+ message_tag: 'nfse:ConsultarNfse',
61
+ message: { :'header!' => "<![CDATA[#{header}]]>",
62
+ :'parameters!' => "<![CDATA[#{parameters}]]>" })
63
+ parse_response(response)
64
+ end
65
+
66
+ def cancelar_nfse(hash = {})
67
+ raise Rnfse::Error::NotImplemented
68
+ end
69
+
70
+ private
71
+
72
+ def validate_ascii(hash)
73
+ raise Rnfse::Error::NonASCIIEncoding unless hash.to_s.ascii_only?
74
+ end
75
+
76
+ def load_options_for_production(options)
77
+ provedor = provedores['producao'][options['provedor'].to_s]
78
+ self.namespace = provedor['namespace']
79
+ municipio = case options['municipio'].to_s
80
+ when 'petrolina' then 'pet'
81
+ when 'aquiraz' then 'aqz'
82
+ else options['municipio'].to_s
83
+ end
84
+ self.endpoint = provedor['endpoint'] % { municipio: municipio }
85
+ load_default_options(options)
86
+ end
87
+
88
+ def parse_response(response)
89
+ hash = Rnfse::Hash.new(response.body)
90
+ response_key = hash.keys.select { |k| k =~ /response$/ }.first
91
+ return_key = hash[response_key].keys.select { |k| k =~ /return$/ }.first
92
+ if !hash[response_key].nil? and hash[response_key]
93
+ xml = hash[response_key][return_key]
94
+ hash[response_key][return_key] = Nori.new.parse(xml)
95
+ end
96
+ hash.underscore_and_symbolize_keys
97
+ end
98
+
99
+ def savon_client_options
100
+ {
101
+ soap_version: 1,
102
+ env_namespace: :soapenv,
103
+ namespaces: { 'xmlns:soapenv' => 'http://schemas.xmlsoap.org/soap/envelope/',
104
+ 'xmlns:nfse' => 'http://www.abrasf.org.br/ABRASF/arquivos/nfse.xsd',
105
+ 'xmlns' => '' },
106
+ namespace_identifier: nil,
107
+ ssl_verify_mode: :peer,
108
+ ssl_cert_file: self.certificate,
109
+ ssl_cert_key_file: self.key,
110
+ endpoint: self.endpoint,
111
+ namespace: self.namespace
112
+ }
113
+ end
114
+
115
+ end
@@ -7,13 +7,13 @@ module Rnfse
7
7
 
8
8
  private
9
9
 
10
- # Stolen from ActionMailer, where this was used but was not made
11
- # reusable
10
+ # Stolen from ActionMailer with a tweek,
11
+ # where this was used but was not made reusable
12
12
  def self.parse_caller(at)
13
- if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
13
+ if /^(.+?):(\d+)(?::in `((block in )?(.*))')?/ =~ at
14
14
  file = Regexp.last_match[1]
15
15
  line = Regexp.last_match[2].to_i
16
- method = Regexp.last_match[3]
16
+ method = Regexp.last_match[5]
17
17
  [file, line, method]
18
18
  end
19
19
  end
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Rnfse
3
+ class Error
4
+ # Metodos não implementados
5
+ class NotImplemented < ::NotImplementedError; end
6
+
7
+ # Ações de API que tem comportamento anômalo.
8
+ # Em alguns provedores algumas ações, embora implemenadas não
9
+ # funcionam ou tem comportamento anômalo.
10
+ class BetterNotBeUsed < ::StandardError; end
11
+
12
+ # Caracteres fora do padrão ASCII foram utilizados.
13
+ class NonASCIIEncoding < ::StandardError; end
14
+ end
15
+ end
@@ -58,18 +58,24 @@ module Rnfse
58
58
  self.class.underscore_and_symbolize_keys(self)
59
59
  end
60
60
 
61
- def self.transform_keys(obj, &block)
61
+ def self.transform_keys(obj, regex = nil, &block)
62
+ regex = /.*/ if regex.nil?
63
+
62
64
  case
63
65
  when obj.kind_of?(::Hash)
64
66
  result = {}
65
67
  obj.each_key do |key|
66
- result[yield(key)] = self.transform_keys(obj[key], &block)
68
+ if regex.match(key)
69
+ result[yield(key)] = self.transform_keys(obj[key], regex, &block)
70
+ else
71
+ result[key] = self.transform_keys(obj[key], regex, &block)
72
+ end
67
73
  end
68
74
  result
69
75
  when obj.kind_of?(::Array)
70
76
  result = []
71
77
  obj.each do |elem|
72
- result << self.transform_keys(elem, &block)
78
+ result << self.transform_keys(elem, regex, &block)
73
79
  end
74
80
  result
75
81
  else
@@ -77,8 +83,8 @@ module Rnfse
77
83
  end
78
84
  end
79
85
 
80
- def transform_keys(&block)
81
- self.class.transform_keys(self, &block)
86
+ def transform_keys(regex = nil, &block)
87
+ self.class.transform_keys(self, regex, &block)
82
88
  end
83
89
 
84
90
  def self.transform_values(obj, key, &block)
@@ -111,19 +117,26 @@ module Rnfse
111
117
  end
112
118
 
113
119
  def self.replace_key_values(obj, key, &block)
114
- parent = key.to_s.split('/').first
115
- childs = key.to_s.split('/')[1..-1]
116
- regex = key.kind_of?(::Regexp) ? key : /\A#{parent}\Z/
120
+ parent, children = case
121
+ when key.kind_of?(::Regexp)
122
+ [ key, [] ]
123
+ when key.kind_of?(::Array)
124
+ [ key.first, key[1..-1] ]
125
+ else
126
+ parts = key.to_s.split('/')
127
+ [ parts.first, parts[1..-1] ]
128
+ end
129
+ regex = parent.kind_of?(::Regexp) ? parent : /\A#{parent}\Z/
117
130
 
118
131
  case
119
132
  when obj.kind_of?(::Hash)
120
133
  result = {}
121
134
  obj.each_key do |k|
122
135
  case
123
- when (regex.match(k) and childs.empty?)
136
+ when (regex.match(k) and children.empty?)
124
137
  result.merge!(yield(k, obj[k]))
125
- when (regex.match(k) and !childs.empty?)
126
- result[k] = self.replace_key_values(obj[k], childs.join('/'), &block)
138
+ when (regex.match(k) and !children.empty?)
139
+ result[k] = self.replace_key_values(obj[k], children, &block)
127
140
  else
128
141
  result[k] = self.replace_key_values(obj[k], key, &block)
129
142
  end
@@ -11,7 +11,7 @@ module Rnfse
11
11
  end
12
12
  string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { $2.capitalize }
13
13
  string.gsub!('/', '::')
14
- string
14
+ self.new(string)
15
15
  end
16
16
 
17
17
  def camelize
@@ -26,11 +26,25 @@ module Rnfse
26
26
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
27
27
  word.tr!("-", "_")
28
28
  word.downcase!
29
- word
29
+ self.new(word)
30
30
  end
31
31
 
32
32
  def underscore
33
33
  self.class.underscore(self)
34
34
  end
35
+
36
+ def self.demodulize(path)
37
+ path = path.to_s
38
+ self.new( if i = path.rindex('::')
39
+ path[(i+2)..-1]
40
+ else
41
+ path
42
+ end )
43
+ end
44
+
45
+ def demodulize
46
+ self.class.demodulize(self)
47
+ end
48
+
35
49
  end
36
50
  end
@@ -1,3 +1,3 @@
1
1
  module Rnfse
2
- VERSION = '0.3.0'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -5,15 +5,51 @@ module Rnfse::XMLBuilder::Abrasf10
5
5
  module ClassMethods
6
6
 
7
7
  def build_recepcionar_lote_rps_xml(hash = {})
8
- build_xml('EnviarLoteRpsEnvio', hash)
8
+ if block_given?
9
+ build_xml('EnviarLoteRpsEnvio', hash, &Proc.new)
10
+ else
11
+ build_xml('EnviarLoteRpsEnvio', hash)
12
+ end
13
+ end
14
+
15
+ def build_consultar_situacao_lote_rps_xml(hash = {})
16
+ if block_given?
17
+ build_xml('ConsultarSituacaoLoteRpsEnvio', hash, &Proc.new)
18
+ else
19
+ build_xml('ConsultarSituacaoLoteRpsEnvio', hash)
20
+ end
21
+ end
22
+
23
+ def build_consultar_nfse_por_rps_xml(hash = {})
24
+ if block_given?
25
+ build_xml('ConsultarNfseRpsEnvio', hash, &Proc.new)
26
+ else
27
+ build_xml('ConsultarNfseRpsEnvio', hash)
28
+ end
29
+ end
30
+
31
+ def build_consultar_nfse_xml(hash = {})
32
+ if block_given?
33
+ build_xml('ConsultarNfseEnvio', hash, &Proc.new)
34
+ else
35
+ build_xml('ConsultarNfseEnvio', hash)
36
+ end
9
37
  end
10
38
 
11
39
  def build_consultar_lote_rps_xml(hash = {})
12
- build_xml('ConsultarLoteRpsEnvio', hash)
40
+ if block_given?
41
+ build_xml('ConsultarLoteRpsEnvio', hash, &Proc.new)
42
+ else
43
+ build_xml('ConsultarLoteRpsEnvio', hash)
44
+ end
13
45
  end
14
46
 
15
- def build_consultar_situacao_lote_rps_xml(hash = {})
16
- build_xml('ConsultarSituacaoLoteRpsEnvio', hash)
47
+ def build_cancelar_nfse_xml(hash = {})
48
+ if block_given?
49
+ build_xml('CancelarNfseEnvio', hash, &Proc.new)
50
+ else
51
+ build_xml('CancelarNfseEnvio', hash)
52
+ end
17
53
  end
18
54
 
19
55
  private
@@ -21,6 +57,7 @@ module Rnfse::XMLBuilder::Abrasf10
21
57
  def build_xml(wrapper, hash = {})
22
58
  hash = prepare_hash(hash)
23
59
  inner_xml = ::Gyoku.xml(hash, key_converter: :none)
60
+ inner_xml = yield(Nokogiri::XML(inner_xml)) if block_given?
24
61
  xml_builder(wrapper, inner_xml).doc
25
62
  end
26
63
 
@@ -28,6 +65,8 @@ module Rnfse::XMLBuilder::Abrasf10
28
65
  def prepare_hash(hash)
29
66
  hash = camelize_hash(hash)
30
67
  hash = wrap_rps(hash)
68
+ hash = wrap_periodo_emissao(hash)
69
+ hash = wrap_identificacao_nfse(hash)
31
70
  hash = add_tc_namespace(hash)
32
71
  hash = clean_numerics(hash)
33
72
  hash = date_to_utc(hash)
@@ -37,7 +76,7 @@ module Rnfse::XMLBuilder::Abrasf10
37
76
 
38
77
  # converte booleanos para 1 ou 2
39
78
  def fix_booleans(hash)
40
- regex = /(IssRetido|OptanteSimplesNacional|IncentivadorCultural)\Z/
79
+ regex = /((?<!Valor)IssRetido|OptanteSimplesNacional|IncentivadorCultural)\Z/
41
80
  Rnfse::Hash.transform_values(hash, regex) do |val|
42
81
  val ? 1 : 2
43
82
  end
@@ -46,7 +85,7 @@ module Rnfse::XMLBuilder::Abrasf10
46
85
  # converte datas para GMT-0
47
86
  def date_to_utc(hash)
48
87
  Rnfse::Hash.transform_values(hash, /DataEmissao\Z/) do |val|
49
- DateTime.parse(val).new_offset(0).strftime('%FT%T')
88
+ DateTime.parse(val.to_s).new_offset(0).strftime('%FT%T')
50
89
  end
51
90
  end
52
91
 
@@ -69,16 +108,43 @@ module Rnfse::XMLBuilder::Abrasf10
69
108
  hash
70
109
  end
71
110
 
111
+ # encapsula as tags data_inicial e data_final em periodo_emissao
112
+ def wrap_periodo_emissao(hash)
113
+ if hash[:DataInicial] or hash[:DataFinal]
114
+ hash[:PeriodoEmissao] = {
115
+ :DataInicial => hash.delete(:DataInicial),
116
+ :DataFinal => hash.delete(:DataFinal)
117
+ }
118
+ end
119
+ hash
120
+ end
121
+
122
+ # encapsula a tag identificacao_nfse
123
+ def wrap_identificacao_nfse(hash)
124
+ if hash[:IdentificacaoNfse]
125
+ hash[:Pedido] = {
126
+ :InfPedidoCancelamento => {
127
+ :IdentificacaoNfse => hash.delete(:IdentificacaoNfse),
128
+ :CodigoCancelamento => hash.delete(:CodigoCancelamento)
129
+ }
130
+ }
131
+ end
132
+ hash
133
+ end
134
+
72
135
  # adiciona o namespace tc nas tags dentro de loteRps ou prestador
73
136
  def add_tc_namespace(hash)
74
- tag = case
75
- when !hash[:LoteRps].nil? then :LoteRps
76
- when !hash[:Prestador].nil? then :Prestador
77
- end
78
- if hash[tag]
79
- hash[tag] = Rnfse::Hash.transform_keys(hash[tag]) { |key| "tc:#{key}".to_sym }
137
+ regex = %r{ \A(
138
+ LoteRps|
139
+ Prestador|
140
+ IdentificacaoRps|
141
+ Tomador|
142
+ IntermediarioServico|
143
+ Pedido
144
+ )\Z }x
145
+ Rnfse::Hash.replace_key_values(hash, regex) do |key, value|
146
+ { key => Rnfse::Hash.transform_keys(value) { |k| "tc:#{k}".to_sym } }
80
147
  end
81
- hash
82
148
  end
83
149
 
84
150
  # namespace dos tipos complexos
@@ -110,6 +176,30 @@ module Rnfse::XMLBuilder::Abrasf10
110
176
  }
111
177
  end
112
178
 
179
+ # namespaces do xml consultar_nfse_por_rps
180
+ def build_consultar_nfse_por_rps_xmlns
181
+ {
182
+ 'xmlns' => 'http://www.abrasf.org.br/servico_consultar_situacao_lote_rps_envio.xsd',
183
+ 'xmlns:tc' => xmlns_tc
184
+ }
185
+ end
186
+
187
+ # namespaces do xml consultar_nfse
188
+ def build_consultar_nfse_xmlns
189
+ {
190
+ 'xmlns' => 'http://www.abrasf.org.br/servico_consultar_nfse_envio.xsd',
191
+ 'xmlns:tc' => xmlns_tc
192
+ }
193
+ end
194
+
195
+ # namespaces do xml cancelar_nfse
196
+ def build_cancelar_nfse_xmlns
197
+ {
198
+ 'xmlns' => 'http://www.abrasf.org.br/servico_cancelar_nfse_envio.xsd',
199
+ 'xmlns:tc' => xmlns_tc
200
+ }
201
+ end
202
+
113
203
  # instancia o builder a ser utilizado na geracao do xml
114
204
  def xml_builder(root, inner_xml, xmlns = {})
115
205
  xmlns = self.send("#{Rnfse::CallChain.caller_method(2)}ns") if xmlns.empty?