nfe-paulistana 0.5.0 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/Gemfile.lock +43 -30
- data/LICENSE +21 -0
- data/README.md +186 -0
- data/Rakefile +10 -0
- data/lib/nfe-paulistana.rb +18 -296
- data/lib/nfe-paulistana/gateway.rb +96 -0
- data/lib/nfe-paulistana/response.rb +36 -0
- data/lib/nfe-paulistana/version.rb +2 -2
- data/lib/nfe-paulistana/xml_builder.rb +395 -0
- data/nfe-paulistana.gemspec +9 -8
- data/test/lib/nfe-paulistana/envio_rps_test.rb +32 -0
- data/test/lib/nfe-paulistana/version_test.rb +7 -0
- data/test/test_helper.rb +4 -0
- metadata +67 -36
- data/test.rb +0 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f4de596a547dbdd16c6cc8a5e2c4ba91f2f127db
|
4
|
+
data.tar.gz: 451ba769c46e515455f7f398dada54870479aa09
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bf0d9cb6004d94bb86777f48c6c2077421cc5b5ba32d05d23c046713f02527f788076c4d87ce1a1c1d39581cfab0924a02cbbd61d086be4d721490b80e63b998
|
7
|
+
data.tar.gz: 398020e018566c6b918372717c3d21f2738d997cfd5e9ff372550b5df4d827a42eb73bcaeda5e93fe75e034310434cc1e1d8dca612a53220aaa5c468cdcc5cf0
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.7
|
data/Gemfile.lock
CHANGED
@@ -1,49 +1,62 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nfe-paulistana (
|
5
|
-
nokogiri
|
6
|
-
savon
|
4
|
+
nfe-paulistana (1.0.5)
|
5
|
+
nokogiri (>= 1.9.1)
|
6
|
+
savon (>= 2.12)
|
7
7
|
signer
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: http://rubygems.org/
|
11
11
|
specs:
|
12
|
-
akami (1.
|
12
|
+
akami (1.3.1)
|
13
13
|
gyoku (>= 0.4.0)
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
nokogiri
|
15
|
+
builder (3.2.4)
|
16
|
+
coderay (1.1.2)
|
17
|
+
gyoku (1.3.1)
|
17
18
|
builder (>= 2.1.2)
|
18
|
-
httpi (
|
19
|
+
httpi (2.4.4)
|
19
20
|
rack
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
socksify
|
22
|
+
method_source (0.8.2)
|
23
|
+
mini_portile2 (2.4.0)
|
24
|
+
minitest (5.4.0)
|
25
|
+
nokogiri (1.9.1)
|
26
|
+
mini_portile2 (~> 2.4.0)
|
27
|
+
nori (2.6.0)
|
28
|
+
pry (0.10.4)
|
29
|
+
coderay (~> 1.1.0)
|
30
|
+
method_source (~> 0.8.1)
|
31
|
+
slop (~> 3.4)
|
32
|
+
pry-nav (0.2.4)
|
33
|
+
pry (>= 0.9.10, < 0.11.0)
|
34
|
+
rack (2.1.4)
|
35
|
+
rake (10.3.2)
|
36
|
+
savon (2.12.0)
|
37
|
+
akami (~> 1.2)
|
33
38
|
builder (>= 2.1.2)
|
34
|
-
gyoku (
|
35
|
-
httpi (~>
|
36
|
-
nokogiri (>= 1.
|
37
|
-
nori (~>
|
38
|
-
wasabi (~>
|
39
|
-
signer (1.
|
39
|
+
gyoku (~> 1.2)
|
40
|
+
httpi (~> 2.3)
|
41
|
+
nokogiri (>= 1.8.1)
|
42
|
+
nori (~> 2.4)
|
43
|
+
wasabi (~> 3.4)
|
44
|
+
signer (1.9.0)
|
40
45
|
nokogiri (>= 1.5.1)
|
41
|
-
|
42
|
-
|
46
|
+
slop (3.6.0)
|
47
|
+
socksify (1.7.1)
|
48
|
+
wasabi (3.5.0)
|
49
|
+
httpi (~> 2.0)
|
50
|
+
nokogiri (>= 1.4.2)
|
43
51
|
|
44
52
|
PLATFORMS
|
45
53
|
ruby
|
46
54
|
|
47
55
|
DEPENDENCIES
|
56
|
+
minitest
|
48
57
|
nfe-paulistana!
|
49
|
-
|
58
|
+
pry-nav
|
59
|
+
rake
|
60
|
+
|
61
|
+
BUNDLED WITH
|
62
|
+
1.17.3
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Iugu
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
Nota Fiscal Paulistana
|
2
|
+
=============
|
3
|
+
|
4
|
+
Instanciando o Gateway
|
5
|
+
--------------------
|
6
|
+
|
7
|
+
gateway = NfePaulistana::Gateway.new(ssl_cert_p12_path: "path/to/certificate.p12", ssl_cert_path: "path/to/certificate.pem", ssl_key_path: "path/to/key.pem", ssl_cert_pass: "password")
|
8
|
+
|
9
|
+
Use Savon (And HTTPI as HTTP interface)
|
10
|
+
-------------------
|
11
|
+
If you experience trouble with the HTTPI cURL adapter:
|
12
|
+
HTTPI.adapter = :net_http
|
13
|
+
|
14
|
+
Install certificate chain
|
15
|
+
-------------------
|
16
|
+
Dont forget to check if you have ca chain installed.
|
17
|
+
More info: https://help.ubuntu.com/community/OpenSSL
|
18
|
+
|
19
|
+
Metodos
|
20
|
+
------------
|
21
|
+
|
22
|
+
**EnvioRPS**
|
23
|
+
|
24
|
+
response = gateway.envio_rps({
|
25
|
+
:cnpj_remetente => "99999999999999",
|
26
|
+
:inscricao_prestador => "99999999",
|
27
|
+
:data_emissao => "AAAA-MM-DD",
|
28
|
+
:email_tomador => "email@email.email",
|
29
|
+
:tipo_rps => "RPS",
|
30
|
+
:serie_rps => "AAAAA",
|
31
|
+
:status_rps => "N",
|
32
|
+
:valor_servicos => "10.00",
|
33
|
+
:aliquota_servicos => "0.05",
|
34
|
+
:tributacao_rps => "T",
|
35
|
+
:numero_rps => "1",
|
36
|
+
:cpf_tomador => "99999999999",
|
37
|
+
:codigo_servico => "99999",
|
38
|
+
:discriminacao => ""
|
39
|
+
})
|
40
|
+
|
41
|
+
**EnvioLoteRPS**
|
42
|
+
|
43
|
+
response = gateway.envio_lote_rps({
|
44
|
+
:cnpj_remetente => "99999999999999",
|
45
|
+
:inscricao_prestador => "99999999",
|
46
|
+
:data_inicio => "AAAA-MM-DD",
|
47
|
+
:data_fim => "AAAA-MM-DD",
|
48
|
+
:qtd_rps => "2",
|
49
|
+
:valor_total_servicos => "20.00",
|
50
|
+
:valor_total_deducoes => "0",
|
51
|
+
:lote_rps => => [{
|
52
|
+
:inscricao_prestador => "99999999",
|
53
|
+
:data_emissao => "AAAA-MM-DD",
|
54
|
+
:email_tomador => "email@email.email",
|
55
|
+
:tipo_rps => "RPS",
|
56
|
+
:serie_rps => "AAAAA",
|
57
|
+
:status_rps => "N",
|
58
|
+
:valor_servicos => "10.00",
|
59
|
+
:aliquota_servicos => "0.05",
|
60
|
+
:tributacao_rps => "T",
|
61
|
+
:numero_rps => "1",
|
62
|
+
:cpf_tomador => "99999999999",
|
63
|
+
:codigo_servico => "99999",
|
64
|
+
:discriminacao => ""
|
65
|
+
},{
|
66
|
+
:inscricao_prestador => "99999999",
|
67
|
+
:data_emissao => "AAAA-MM-DD",
|
68
|
+
:email_tomador => "email@email.email",
|
69
|
+
:tipo_rps => "RPS",
|
70
|
+
:serie_rps => "AAAAA",
|
71
|
+
:status_rps => "N",
|
72
|
+
:valor_servicos => "10.00",
|
73
|
+
:aliquota_servicos => "0.05",
|
74
|
+
:tributacao_rps => "T",
|
75
|
+
:numero_rps => "2",
|
76
|
+
:cpf_tomador => "99999999999",
|
77
|
+
:codigo_servico => "99999",
|
78
|
+
:discriminacao => ""
|
79
|
+
}]
|
80
|
+
})
|
81
|
+
|
82
|
+
**TesteEnvioLoteRPS**
|
83
|
+
|
84
|
+
response = gateway.teste_envio_lote_rps({
|
85
|
+
:cnpj_remetente => "99999999999999",
|
86
|
+
:inscricao_prestador => "99999999",
|
87
|
+
:data_inicio => "AAAA-MM-DD",
|
88
|
+
:data_fim => "AAAA-MM-DD",
|
89
|
+
:qtd_rps => "2",
|
90
|
+
:valor_total_servicos => "20.00",
|
91
|
+
:valor_total_deducoes => "0",
|
92
|
+
:lote_rps => => [{
|
93
|
+
:inscricao_prestador => "99999999",
|
94
|
+
:data_emissao => "AAAA-MM-DD",
|
95
|
+
:email_tomador => "email@email.email",
|
96
|
+
:tipo_rps => "RPS",
|
97
|
+
:serie_rps => "AAAAA",
|
98
|
+
:status_rps => "N",
|
99
|
+
:valor_servicos => "10.00",
|
100
|
+
:aliquota_servicos => "0.05",
|
101
|
+
:tributacao_rps => "T",
|
102
|
+
:numero_rps => "1",
|
103
|
+
:cpf_tomador => "99999999999",
|
104
|
+
:codigo_servico => "99999",
|
105
|
+
:discriminacao => ""
|
106
|
+
},{
|
107
|
+
:inscricao_prestador => "99999999",
|
108
|
+
:data_emissao => "AAAA-MM-DD",
|
109
|
+
:email_tomador => "email@email.email",
|
110
|
+
:tipo_rps => "RPS",
|
111
|
+
:serie_rps => "AAAAA",
|
112
|
+
:status_rps => "N",
|
113
|
+
:valor_servicos => "10.00",
|
114
|
+
:aliquota_servicos => "0.05",
|
115
|
+
:tributacao_rps => "T",
|
116
|
+
:numero_rps => "2",
|
117
|
+
:cpf_tomador => "99999999999",
|
118
|
+
:codigo_servico => "99999",
|
119
|
+
:discriminacao => ""
|
120
|
+
}]
|
121
|
+
})
|
122
|
+
|
123
|
+
**ConsultaNFe**
|
124
|
+
|
125
|
+
response = gateway.consulta_nfe({
|
126
|
+
cnpj_remetente: "99999999999999",
|
127
|
+
inscricao_prestador: "99999999",
|
128
|
+
numero_nfe: "9"
|
129
|
+
})
|
130
|
+
|
131
|
+
response = gateway.consulta_nfe({
|
132
|
+
cnpj_remetente: "99999999999999",
|
133
|
+
numero_rps: "9",
|
134
|
+
serie_rps: "AAAAA"
|
135
|
+
})
|
136
|
+
|
137
|
+
**ConsultaNFeRecebidas**
|
138
|
+
|
139
|
+
response = gateway.consulta_nfe_recebidas({
|
140
|
+
cnpj_remetente: "99999999999999",
|
141
|
+
cnpj: "99999999999999",
|
142
|
+
data_inicio: "AAAA-MM-DD",
|
143
|
+
data_fim: "AAAA-MM-DD",
|
144
|
+
inscricao: "99999999"
|
145
|
+
})
|
146
|
+
|
147
|
+
|
148
|
+
**ConsultaNFeEmitidas**
|
149
|
+
|
150
|
+
response = gateway.consulta_nfe_emitidas({
|
151
|
+
cnpj_remetente: "99999999999999",
|
152
|
+
cnpj: "99999999999999",
|
153
|
+
data_inicio: "AAAA-MM-DD",
|
154
|
+
data_fim: "AAAA-MM-DD",
|
155
|
+
inscricao: "99999999"
|
156
|
+
})
|
157
|
+
|
158
|
+
**ConsultaLote**
|
159
|
+
|
160
|
+
response = gateway.consulta_lote({
|
161
|
+
:cnpj_remetente => "99999999999999",
|
162
|
+
:numero_lote => "9"
|
163
|
+
})
|
164
|
+
|
165
|
+
**ConsultaInformacoesLote**
|
166
|
+
|
167
|
+
response = gateway.consulta_informacoes_lote({
|
168
|
+
:cnpj_remetente => "99999999999999",
|
169
|
+
:inscricao_prestador => "99999999",
|
170
|
+
:numero_lote => "9"
|
171
|
+
})
|
172
|
+
|
173
|
+
**CancelamentoNFe**
|
174
|
+
|
175
|
+
response = gateway.cancelamento_nfe({
|
176
|
+
cnpj_remetente: "99999999999999",
|
177
|
+
inscricao_prestador: "99999999",
|
178
|
+
numero_nfe: "9"
|
179
|
+
})
|
180
|
+
|
181
|
+
**ConsultaCNPJ**
|
182
|
+
|
183
|
+
response = gateway.consulta_cnpj({
|
184
|
+
cnpj_remetente: "99999999999999",
|
185
|
+
cnpj_contribuinte: "99999999999999"
|
186
|
+
})
|
data/Rakefile
CHANGED
data/lib/nfe-paulistana.rb
CHANGED
@@ -1,316 +1,38 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
require "nfe-paulistana/version"
|
4
|
+
require "nfe-paulistana/xml_builder"
|
5
|
+
require "nfe-paulistana/response"
|
6
|
+
require "nfe-paulistana/gateway"
|
4
7
|
require "signer"
|
5
8
|
require "savon"
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
default_options = {
|
10
|
-
:cpf_remetente => '',
|
11
|
-
:cnpj_remetente => '',
|
12
|
-
:inscricao_prestador => '',
|
13
|
-
:serie_rps => '',
|
14
|
-
:numero_rps => '',
|
15
|
-
:tipo_rps => '',
|
16
|
-
:data_emissao => '',
|
17
|
-
:status_rps => '',
|
18
|
-
:tributacao_rps => '',
|
19
|
-
:valor_servicos => '0',
|
20
|
-
:valor_deducoes => '0',
|
21
|
-
:valor_pis => '0',
|
22
|
-
:valor_cofins => '0',
|
23
|
-
:valor_inss => '0',
|
24
|
-
:valor_ir => '0',
|
25
|
-
:valor_csll => '0',
|
26
|
-
:codigo_servico => '0',
|
27
|
-
:aliquota_servicos => '0',
|
28
|
-
:iss_retido => false,
|
29
|
-
:cpf_tomador => '',
|
30
|
-
:cnpj_tomador => '',
|
31
|
-
:im_tomador => '',
|
32
|
-
:ie_tomador => '',
|
33
|
-
:razao_tomador => '',
|
34
|
-
:tp_logradouro => '',
|
35
|
-
:logradouro => '',
|
36
|
-
:nr_endereco => '',
|
37
|
-
:compl_endereco => '',
|
38
|
-
:bairro => '',
|
39
|
-
:cidade => '',
|
40
|
-
:uf => '',
|
41
|
-
:cep => '',
|
42
|
-
:email_tomador => '',
|
43
|
-
:discriminacao => '',
|
44
|
-
:cert_path => '',
|
45
|
-
:cert_pass => '',
|
46
|
-
:wsdl => 'https://nfe.prefeitura.sp.gov.br/ws/lotenfe.asmx?wsdl'
|
47
|
-
}
|
10
|
+
module NfePaulistana
|
11
|
+
WSDL = 'https://nfe.prefeitura.sp.gov.br/ws/lotenfe.asmx?wsdl'
|
48
12
|
|
49
|
-
|
13
|
+
def self.enviar(data = {})
|
14
|
+
certificado = OpenSSL::PKCS12.new(File.read(data[:cert_path]), data[:cert_pass])
|
15
|
+
client = get_client(certificado)
|
50
16
|
|
51
|
-
@certificado = OpenSSL::PKCS12.new(File.read(@options[:cert_path]), @options[:cert_pass])
|
52
|
-
end
|
53
|
-
|
54
|
-
def enviar
|
55
|
-
client = Savon::Client.new do |wsdl, http|
|
56
|
-
wsdl.document = @options[:wsdl]
|
57
|
-
# http.auth.ssl.cert_key_file = "/Users/patricknegri/Desenvolvimento/Certificado-Iugu-Chave.pem"
|
58
|
-
# http.auth.ssl.cert_file = "/Users/patricknegri/Desenvolvimento/Certificado-Iugu.pem"
|
59
|
-
http.auth.ssl.cert_key = @certificado.key
|
60
|
-
http.auth.ssl.cert = @certificado.certificate
|
61
|
-
http.auth.ssl.verify_mode = :peer
|
62
|
-
|
63
|
-
# http.ssl_client_auth( :cert => @certificado, :key => @certificado.key, :verify_mode => OpenSSL::SSL::VERIFY_NONE )
|
64
|
-
# http.auth.ssl.cert = @certificado
|
65
|
-
# http.auth.ssl.key = @certificado.key
|
66
|
-
# http.auth.ssl.verify_mode = :none
|
67
|
-
end
|
68
|
-
|
69
|
-
Savon.configure do |config|
|
70
|
-
config.soap_version = 2
|
71
|
-
end
|
72
|
-
Savon.env_namespace = :soap
|
73
|
-
|
74
|
-
#http.ssl_client_auth( :cert => @certificado, :key => @certificado.key, :verify_mode => OpenSSL::SSL::VERIFY_NONE )
|
75
|
-
|
76
17
|
begin
|
77
|
-
response = client.
|
78
|
-
|
18
|
+
response = client.call(:envio_rps, message: {
|
19
|
+
input: [
|
79
20
|
"EnvioRPSRequest",
|
80
21
|
{"xmlns" => "http://www.prefeitura.sp.gov.br/nfe"}
|
81
|
-
]
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
soap.body = doc_txt
|
88
|
-
|
89
|
-
# soap.body = assinar( to_xml )
|
90
|
-
soap.version = 2
|
91
|
-
end
|
92
|
-
@retorno_xml = response.to_hash[:envio_rps_response][:retorno_xml]
|
93
|
-
@retorno = Nori.parse( retorno_xml )[:retorno_envio_rps]
|
94
|
-
@success = @retorno[:cabecalho][:sucesso]
|
22
|
+
],
|
23
|
+
body: XmlBuilder.new.xml_for(:envio_rps, data, certificado),
|
24
|
+
version: 2
|
25
|
+
})
|
26
|
+
Response.new(xml: response.hash[:envio_rps_response][:retorno_xml], method: :envio_rps_response)
|
95
27
|
rescue Savon::Error => error
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
def retorno_xml
|
100
|
-
@retorno_xml
|
101
|
-
end
|
102
|
-
|
103
|
-
def retorno
|
104
|
-
@retorno
|
105
|
-
end
|
106
|
-
|
107
|
-
def success?
|
108
|
-
!!@success
|
109
|
-
end
|
110
|
-
|
111
|
-
def error
|
112
|
-
if !success?
|
113
|
-
errors = retorno[:alerta] || retorno[:erro]
|
114
|
-
errors.try('[]', :descricao)
|
28
|
+
error
|
115
29
|
end
|
116
30
|
end
|
117
31
|
|
118
32
|
private
|
119
|
-
|
120
|
-
def assinar(xml)
|
121
|
-
|
122
|
-
xml = Nokogiri::XML(xml.to_s, &:noblanks)
|
123
|
-
|
124
|
-
# 1. Digest Hash for all XML
|
125
|
-
xml_canon = xml.canonicalize(Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0)
|
126
|
-
xml_digest = Base64.encode64(OpenSSL::Digest::SHA1.digest(xml_canon)).strip
|
127
|
-
|
128
|
-
# 2. Add Signature Node
|
129
|
-
signature = xml.xpath("//ds:Signature", "ds" => "http://www.w3.org/2000/09/xmldsig#").first
|
130
|
-
unless signature
|
131
|
-
signature = Nokogiri::XML::Node.new('Signature', xml)
|
132
|
-
signature.default_namespace = 'http://www.w3.org/2000/09/xmldsig#'
|
133
|
-
xml.root().add_child(signature)
|
134
|
-
end
|
135
|
-
|
136
|
-
# 3. Add Elements to Signature Node
|
137
|
-
|
138
|
-
# 3.1 Create Signature Info
|
139
|
-
signature_info = Nokogiri::XML::Node.new('SignedInfo', xml)
|
140
|
-
|
141
|
-
# 3.2 Add CanonicalizationMethod
|
142
|
-
child_node = Nokogiri::XML::Node.new('CanonicalizationMethod', xml)
|
143
|
-
child_node['Algorithm'] = 'http://www.w3.org/2001/10/xml-exc-c14n#'
|
144
|
-
signature_info.add_child child_node
|
145
33
|
|
146
|
-
|
147
|
-
|
148
|
-
child_node['Algorithm'] = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
|
149
|
-
signature_info.add_child child_node
|
150
|
-
|
151
|
-
# 3.4 Create Reference
|
152
|
-
reference = Nokogiri::XML::Node.new('Reference', xml)
|
153
|
-
reference['URI'] = ''
|
154
|
-
|
155
|
-
# 3.5 Add Transforms
|
156
|
-
transforms = Nokogiri::XML::Node.new('Transforms', xml)
|
157
|
-
|
158
|
-
child_node = Nokogiri::XML::Node.new('Transform', xml)
|
159
|
-
child_node['Algorithm'] = 'http://www.w3.org/2000/09/xmldsig#enveloped-signature'
|
160
|
-
transforms.add_child child_node
|
161
|
-
|
162
|
-
child_node = Nokogiri::XML::Node.new('Transform', xml)
|
163
|
-
child_node['Algorithm'] = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
|
164
|
-
transforms.add_child child_node
|
165
|
-
|
166
|
-
reference.add_child transforms
|
167
|
-
|
168
|
-
# 3.6 Add Digest
|
169
|
-
child_node = Nokogiri::XML::Node.new('DigestMethod', xml)
|
170
|
-
child_node['Algorithm'] = 'http://www.w3.org/2000/09/xmldsig#sha1'
|
171
|
-
reference.add_child child_node
|
172
|
-
|
173
|
-
# 3.6 Add DigestValue
|
174
|
-
child_node = Nokogiri::XML::Node.new('DigestValue', xml)
|
175
|
-
child_node.content = xml_digest
|
176
|
-
reference.add_child child_node
|
177
|
-
|
178
|
-
# 3.7 Add Reference and Signature Info
|
179
|
-
signature_info.add_child reference
|
180
|
-
signature.add_child signature_info
|
181
|
-
|
182
|
-
# 4 Sign Signature
|
183
|
-
sign_canon = signature_info.canonicalize(Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0)
|
184
|
-
signature_hash = @certificado.key.sign(OpenSSL::Digest::SHA1.new, sign_canon)
|
185
|
-
signature_value = Base64.encode64( signature_hash ).gsub("\n", '')
|
186
|
-
|
187
|
-
# 4.1 Add SignatureValue
|
188
|
-
child_node = Nokogiri::XML::Node.new('SignatureValue', xml)
|
189
|
-
child_node.content = signature_value
|
190
|
-
signature.add_child child_node
|
191
|
-
|
192
|
-
# 5 Create KeyInfo
|
193
|
-
key_info = Nokogiri::XML::Node.new('KeyInfo', xml)
|
194
|
-
|
195
|
-
# 5.1 Add X509 Data and Certificate
|
196
|
-
x509_data = Nokogiri::XML::Node.new('X509Data', xml)
|
197
|
-
x509_certificate = Nokogiri::XML::Node.new('X509Certificate', xml)
|
198
|
-
x509_certificate.content = @certificado.certificate.to_s.gsub(/\-\-\-\-\-[A-Z]+ CERTIFICATE\-\-\-\-\-/, "").gsub(/\n/,"")
|
199
|
-
|
200
|
-
x509_data.add_child x509_certificate
|
201
|
-
key_info.add_child x509_data
|
202
|
-
|
203
|
-
# 5.2 Add KeyInfo
|
204
|
-
signature.add_child key_info
|
205
|
-
|
206
|
-
# 6 Add Signature
|
207
|
-
xml.root().add_child signature
|
208
|
-
|
209
|
-
# Return XML
|
210
|
-
xml.canonicalize(Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0)
|
211
|
-
# xml.to_xml( :save_with => 0 )
|
212
|
-
end
|
213
|
-
|
214
|
-
def assinatura_simples
|
215
|
-
value = @options[:inscricao_prestador].rjust(8,'0') + @options[:serie_rps].ljust(5) + @options[:numero_rps].rjust(12,'0') + @options[:data_emissao].delete('-') \
|
216
|
-
+ @options[:tributacao_rps] + @options[:status_rps] + (@options[:iss_retido] ? 'S' : 'N') + @options[:valor_servicos].delete(',').delete('.').rjust(15,'0') \
|
217
|
-
+ @options[:valor_deducoes].delete(',').delete('.').rjust(15,'0') + @options[:codigo_servico].rjust(5,'0') \
|
218
|
-
+ (@options[:cpf_tomador].blank? ? (@options[:cnpj_tomador].blank? ? '3' : '2') : '1') \
|
219
|
-
+ (@options[:cpf_tomador].blank? ? (@options[:cnpj_tomador].blank? ? "".rjust(14,'0') : @options[:cnpj_tomador]) : @options[:cpf_tomador])
|
220
|
-
|
221
|
-
part_1 = @options[:inscricao_prestador].rjust(8,'0')
|
222
|
-
part_2 = @options[:serie_rps].ljust(5)
|
223
|
-
part_3 = @options[:numero_rps].rjust(12,'0')
|
224
|
-
part_4 = @options[:data_emissao].delete('-')
|
225
|
-
part_5 = @options[:tributacao_rps]
|
226
|
-
part_6 = @options[:status_rps]
|
227
|
-
part_7 = @options[:iss_retido] ? 'S' : 'N'
|
228
|
-
part_8 = @options[:valor_servicos].delete(',').delete('.').rjust(15,'0')
|
229
|
-
part_9 = @options[:valor_deducoes].delete(',').delete('.').rjust(15,'0')
|
230
|
-
part_10 = @options[:codigo_servico].rjust(5,'0')
|
231
|
-
part_11 = (@options[:cpf_tomador].blank? ? (@options[:cnpj_tomador].blank? ? '3' : '2') : '1')
|
232
|
-
part_12 = (@options[:cpf_tomador].blank? ? (@options[:cnpj_tomador].blank? ? "".rjust(14,'0') : @options[:cnpj_tomador].rjust(14,'0') ) : @options[:cpf_tomador].rjust(14,'0'))
|
233
|
-
|
234
|
-
value = part_1 + part_2 + part_3 + part_4 + part_5 + part_6 + part_7 + part_8 + part_9 + part_10 + part_11 + part_12
|
235
|
-
|
236
|
-
# PHP Sign
|
237
|
-
# $digestValue = base64_encode( hash( 'sha1', $content, true ) );
|
238
|
-
# $pkeyId = openssl_get_privatekey( file_get_contents( $this->privateKey ) );
|
239
|
-
# openssl_sign( $digestValue, $signatureValue, $pkeyId );
|
240
|
-
|
241
|
-
# a_hash = OpenSSL::Digest::SHA1.digest( value )
|
242
|
-
# Base64.encode64( @certificado.key.private_encrypt( value ) ).gsub("\n",'').strip()
|
243
|
-
|
244
|
-
sign_hash = @certificado.key.sign( OpenSSL::Digest::SHA1.new, value )
|
245
|
-
Base64.encode64( sign_hash ).gsub("\n",'').gsub("\r",'').strip()
|
246
|
-
end
|
247
|
-
|
248
|
-
def to_xml
|
249
|
-
builder = Nokogiri::XML::Builder.new do |xml|
|
250
|
-
xml.PedidoEnvioRPS( "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns" => "http://www.prefeitura.sp.gov.br/nfe" ) {
|
251
|
-
xml.Cabecalho( "Versao" => "1", :xmlns => "" ) {
|
252
|
-
xml.CPFCNPJRemetente {
|
253
|
-
xml.CPF @options[:cpf_remetente] unless @options[:cpf_remetente].blank?
|
254
|
-
xml.CNPJ @options[:cnpj_remetente] unless @options[:cnpj_remetente].blank?
|
255
|
-
}
|
256
|
-
}
|
257
|
-
xml.RPS( :xmlns => "" ) {
|
258
|
-
xml.Assinatura assinatura_simples()
|
259
|
-
xml.ChaveRPS {
|
260
|
-
xml.InscricaoPrestador @options[:inscricao_prestador]
|
261
|
-
xml.SerieRPS @options[:serie_rps] unless @options[:serie_rps].blank?
|
262
|
-
xml.NumeroRPS @options[:numero_rps] unless @options[:numero_rps].blank?
|
263
|
-
}
|
264
|
-
xml.TipoRPS @options[:tipo_rps]
|
265
|
-
xml.DataEmissao @options[:data_emissao]
|
266
|
-
xml.StatusRPS @options[:status_rps]
|
267
|
-
xml.TributacaoRPS @options[:tributacao_rps]
|
268
|
-
xml.ValorServicos @options[:valor_servicos]
|
269
|
-
xml.ValorDeducoes @options[:valor_deducoes]
|
270
|
-
xml.ValorPIS @options[:valor_pis] if @options[:valor_pis] != '0'
|
271
|
-
xml.ValorCOFINS @options[:valor_cofins] if @options[:valor_cofins] != '0'
|
272
|
-
xml.ValorINSS @options[:valor_inss] if @options[:valor_inss] != '0'
|
273
|
-
xml.ValorIR @options[:valor_ir] if @options[:valor_ir] != '0'
|
274
|
-
xml.ValorCSLL @options[:valor_csll] if @options[:valor_csll] != '0'
|
275
|
-
xml.CodigoServico @options[:codigo_servico]
|
276
|
-
xml.AliquotaServicos @options[:aliquota_servicos]
|
277
|
-
xml.ISSRetido @options[:iss_retido]
|
278
|
-
unless (@options[:cpf_tomador].blank? and @options[:cnpj_tomador].blank?)
|
279
|
-
xml.CPFCNPJTomador {
|
280
|
-
xml.CPF @options[:cpf_tomador] unless @options[:cpf_tomador].blank?
|
281
|
-
xml.CNPJ @options[:cnpj_tomador] unless @options[:cnpj_tomador].blank?
|
282
|
-
}
|
283
|
-
end
|
284
|
-
xml.InscricaoMunicipalTomador @options[:im_tomador] unless @options[:im_tomador]
|
285
|
-
xml.InscricaoEstadualTomador @options[:ie_tomador] unless @options[:ie_tomador]
|
286
|
-
xml.RazaoSocialTomador @options[:razao_tomador] unless @options[:razao_tomador]
|
287
|
-
unless (@options[:tp_logradouro].blank? and @options[:logradouro].blank? and @options[:nr_endereco] and @options[:compl_endereco])
|
288
|
-
xml.EnderecoTomador {
|
289
|
-
xml.TipoLogradouro @options[:tp_logradouro]
|
290
|
-
xml.Logradouro @options[:logradouro]
|
291
|
-
xml.NumeroEndereco @options[:nr_endereco]
|
292
|
-
xml.ComplementoEndereco @options[:compl_endereco]
|
293
|
-
xml.Bairro @options[:bairro] unless @options[:bairro].blank?
|
294
|
-
xml.Cidade @options[:cidade] unless @options[:cidade].blank?
|
295
|
-
xml.UF @options[:uf] unless @options[:uf]
|
296
|
-
xml.CEP @options[:cep] unless @options[:cep]
|
297
|
-
}
|
298
|
-
end
|
299
|
-
xml.EmailTomador @options[:email_tomador]
|
300
|
-
xml.Discriminacao @options[:discriminacao]
|
301
|
-
}
|
302
|
-
# xml.Signature( "xmlns" => "http://www.w3.org/2000/09/xmldsig#" ) {
|
303
|
-
# TODO: These elements must be added later, after the sign
|
304
|
-
# xml.KeyInfo {
|
305
|
-
# xml.X509Data {
|
306
|
-
# xml.X509Certificate @certificado.certificate.to_s.gsub(/\-\-\-\-\-[A-Z]+ CERTIFICATE\-\-\-\-\-/, "").gsub(/\n/,"")
|
307
|
-
# }
|
308
|
-
# }
|
309
|
-
# }
|
310
|
-
}
|
311
|
-
end
|
312
|
-
# builder.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).gsub("<root>","").gsub("</root>","").gsub("\n","")
|
313
|
-
Nokogiri::XML( builder.to_xml( :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION ) )
|
34
|
+
def get_client(certificado)
|
35
|
+
Savon.client(soap_version: 2, env_namespace: :soap, ssl_verify_mode: :peer, ssl_cert_file: certificado.certificate, ssl_cert_key_file: certificado.key, wsdl: WSDL)
|
314
36
|
end
|
315
37
|
|
316
38
|
end
|