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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +7 -6
- data/lib/provedores.yml +8 -0
- data/lib/rnfse.rb +5 -1
- data/lib/rnfse/api.rb +44 -22
- data/lib/rnfse/api/abrasf_1_0.rb +100 -17
- data/lib/rnfse/api/abrasf_1_0/#definitions.json# +413 -0
- data/lib/rnfse/api/abrasf_1_0/cancelar_nfse.json +13 -0
- data/lib/rnfse/api/abrasf_1_0/consultar_nfse.json +17 -0
- data/lib/rnfse/api/abrasf_1_0/consultar_nfse_por_rps.json +13 -0
- data/lib/rnfse/api/abrasf_1_0/definitions.json +27 -3
- data/lib/rnfse/api/abrasf_1_0/recepcionar_lote_rps.json +1 -1
- data/lib/rnfse/api/iss_net_1_0.rb +46 -2
- data/lib/rnfse/api/speed_gov_1_0.rb +115 -0
- data/lib/rnfse/call_chain.rb +4 -4
- data/lib/rnfse/error.rb +15 -0
- data/lib/rnfse/hash.rb +24 -11
- data/lib/rnfse/string.rb +16 -2
- data/lib/rnfse/version.rb +1 -1
- data/lib/rnfse/xml_builder/abrasf_1_0.rb +103 -13
- data/lib/rnfse/xml_builder/iss_net_1_0.rb +34 -4
- data/lib/rnfse/xml_builder/speed_gov_1_0.rb +158 -0
- data/spec/api/abrasf_1_0/cancelar_nfse_json_spec.rb +25 -0
- data/spec/api/abrasf_1_0/consultar_lote_rps_json_spec.rb +23 -0
- data/spec/api/abrasf_1_0/consultar_nfse_json_spec.rb +45 -0
- data/spec/api/abrasf_1_0/consultar_nfse_por_rps_json_spec.rb +23 -0
- data/spec/api/abrasf_1_0/consultar_situacao_lote_rps_json_spec.rb +23 -0
- data/spec/api/abrasf_1_0_spec.rb +185 -6
- data/spec/api/iss_net_1_0_spec.rb +89 -9
- data/spec/api/speed_gov_1_0_spec.rb +243 -0
- data/spec/api_spec.rb +43 -28
- data/spec/error_spec.rb +10 -0
- data/spec/fixtures/abrasf_1_0/cancelar_nfse_envio.xml +16 -0
- data/spec/fixtures/abrasf_1_0/consultar_nfse.xml +23 -0
- data/spec/fixtures/abrasf_1_0/consultar_nfse_por_rps.xml +14 -0
- data/spec/fixtures/iss_net_1_0/cancelar_nfse_envio.xml +17 -0
- data/spec/fixtures/iss_net_1_0/consultar_nfse.xml +29 -0
- data/spec/fixtures/iss_net_1_0/consultar_nfse_por_rps.xml +17 -0
- data/spec/fixtures/speed_gov_1_0/consultar_nfse_envio.xml +29 -0
- data/spec/fixtures/speed_gov_1_0/consultar_nfse_rps_envio.xml +16 -0
- data/spec/fixtures/speed_gov_1_0/consultar_situacao_lote_rps_envio.xml +12 -0
- data/spec/fixtures/speed_gov_1_0/enviar_lote_rps_envio.xml +82 -0
- data/spec/fixtures/speed_gov_1_0/header.xml +9 -0
- data/spec/fixtures/vcr_cassettes/iss_net_1_0_cancelar_nfse.yml +107 -0
- data/spec/fixtures/vcr_cassettes/iss_net_1_0_consultar_nfse.yml +7937 -0
- data/spec/fixtures/vcr_cassettes/iss_net_1_0_consultar_nfse_por_rps.yml +242 -0
- data/spec/fixtures/vcr_cassettes/speed_gov_1_0_consultar_nfse.yml +60 -0
- data/spec/fixtures/vcr_cassettes/speed_gov_1_0_consultar_nfse_por_rps.yml +80 -0
- data/spec/fixtures/vcr_cassettes/speed_gov_1_0_consultar_situacao_lote_rps.yml +77 -0
- data/spec/fixtures/vcr_cassettes/speed_gov_1_0_recepcionar_lote_rps.yml +171 -0
- data/spec/fixtures/vcr_cassettes/speed_gov_1_0_recepcionar_lote_rps_ascii.yml +171 -0
- data/spec/hash_spec.rb +21 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/string_spec.rb +31 -5
- data/spec/xml_builder/abrasf_1_0_spec.rb +110 -43
- data/spec/xml_builder/iss_net_1_0_spec.rb +111 -44
- data/spec/xml_builder/speed_gov_1_0_spec.rb +173 -0
- metadata +86 -37
- data/.gitignore +0 -25
- data/.rspec +0 -1
- data/.travis.yml +0 -14
- data/Gemfile +0 -3
- data/Guardfile +0 -15
- data/Procfile +0 -1
- data/Rakefile +0 -12
- data/rnfse.gemspec +0 -61
- data/spec/fixtures/abrasf_1_0/teste.xml +0 -8
- 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":
|
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":
|
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
|
-
"
|
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": { "
|
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
|
-
|
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
|
data/lib/rnfse/call_chain.rb
CHANGED
@@ -7,13 +7,13 @@ module Rnfse
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
# Stolen from ActionMailer
|
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[
|
16
|
+
method = Regexp.last_match[5]
|
17
17
|
[file, line, method]
|
18
18
|
end
|
19
19
|
end
|
data/lib/rnfse/error.rb
ADDED
@@ -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
|
data/lib/rnfse/hash.rb
CHANGED
@@ -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
|
-
|
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 =
|
115
|
-
|
116
|
-
|
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
|
136
|
+
when (regex.match(k) and children.empty?)
|
124
137
|
result.merge!(yield(k, obj[k]))
|
125
|
-
when (regex.match(k) and !
|
126
|
-
result[k] = self.replace_key_values(obj[k],
|
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
|
data/lib/rnfse/string.rb
CHANGED
@@ -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
|
data/lib/rnfse/version.rb
CHANGED
@@ -5,15 +5,51 @@ module Rnfse::XMLBuilder::Abrasf10
|
|
5
5
|
module ClassMethods
|
6
6
|
|
7
7
|
def build_recepcionar_lote_rps_xml(hash = {})
|
8
|
-
|
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
|
-
|
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
|
16
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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?
|