rnfse 0.3.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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?
|