br_nfe 1.0.0 → 1.0.1
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/Gemfile.lock +4 -1
- data/README.markdown +263 -1
- data/br_nfe.gemspec +14 -5
- data/lib/br_nfe/base.rb +6 -1
- data/lib/br_nfe/helper/cpf_cnpj.rb +0 -5
- data/lib/br_nfe/helper/have_address.rb +1 -5
- data/lib/br_nfe/helper/have_rps.rb +7 -0
- data/lib/br_nfe/servico/betha/base.rb +52 -41
- data/lib/br_nfe/servico/betha/build_response.rb +141 -0
- data/lib/br_nfe/servico/betha/v1/build_response.rb +4 -102
- data/lib/br_nfe/servico/betha/v1/consulta_lote_rps.rb +3 -1
- data/lib/br_nfe/servico/betha/v1/consulta_nfs_por_rps.rb +5 -2
- data/lib/br_nfe/servico/betha/v1/consulta_nfse.rb +2 -1
- data/lib/br_nfe/servico/betha/v1/gateway.rb +66 -56
- data/lib/br_nfe/servico/betha/v1/recepcao_lote_rps.rb +16 -8
- data/lib/br_nfe/servico/betha/v2/build_response.rb +159 -0
- data/lib/br_nfe/servico/betha/v2/cancelamento_nfs.rb +8 -3
- data/lib/br_nfe/servico/betha/v2/consulta_lote_rps.rb +7 -4
- data/lib/br_nfe/servico/betha/v2/consulta_nfse_por_rps.rb +5 -5
- data/lib/br_nfe/servico/betha/v2/envio_lote_rps_sincrono.rb +7 -3
- data/lib/br_nfe/servico/betha/v2/gateway.rb +79 -56
- data/lib/br_nfe/servico/betha/v2/gera_nfse.rb +8 -3
- data/lib/br_nfe/servico/betha/v2/recepcao_lote_rps.rb +9 -4
- data/lib/br_nfe/servico/betha/v2/substituicao_nfse.rb +8 -4
- data/lib/br_nfe/servico/response/nota_fiscal.rb +13 -4
- data/lib/br_nfe/servico/rps.rb +2 -2
- data/lib/br_nfe/version.rb +1 -1
- data/lib/br_nfe.rb +2 -1
- data/test/br_nfe/base_test.rb +55 -1
- data/test/br_nfe/destinatario_test.rb +19 -0
- data/test/br_nfe/emitente_test.rb +20 -0
- data/test/br_nfe/endereco_test.rb +9 -0
- data/test/br_nfe/helper/cpf_cnpj_test.rb +61 -0
- data/test/br_nfe/servico/base_test.rb +28 -0
- data/test/br_nfe/servico/betha/base_test.rb +61 -32
- data/test/br_nfe/servico/betha/v1/build_response_test.rb +6 -7
- data/test/br_nfe/servico/betha/v1/cancelamento_nfs_test.rb +6 -0
- data/test/br_nfe/servico/betha/v1/consulta_lote_rps_test.rb +4 -0
- data/test/br_nfe/servico/betha/v1/consulta_nfse_test.rb +17 -0
- data/test/br_nfe/servico/betha/v1/gateway_test.rb +17 -40
- data/test/br_nfe/servico/betha/v1/recepcao_lote_rps_test.rb +12 -2
- data/test/br_nfe/servico/betha/v2/cancelamento_nfs_test.rb +40 -0
- data/test/br_nfe/servico/betha/v2/consulta_lote_rps_test.rb +38 -0
- data/test/br_nfe/servico/betha/v2/consulta_nfse_por_rps_test.rb +36 -0
- data/test/br_nfe/servico/betha/v2/envio_lote_rps_sincrono_test.rb +46 -0
- data/test/br_nfe/servico/betha/v2/gateway_test.rb +372 -0
- data/test/br_nfe/servico/betha/v2/gera_nfse_test.rb +58 -0
- data/test/br_nfe/servico/betha/v2/recepcao_lote_rps_test.rb +103 -0
- data/test/br_nfe/servico/betha/v2/substituicao_nfse_test.rb +80 -0
- data/test/br_nfe/servico/intermediario_test.rb +16 -0
- data/test/br_nfe/servico/rps_test.rb +141 -0
- data/test/factories/servico/betha/v1/gateway.rb +1 -1
- data/test/factories/servico/betha/v2/cancelamento_nfs.rb +7 -0
- data/test/factories/servico/betha/v2/consulta_lote_rps.rb +6 -0
- data/test/factories/servico/betha/v2/consulta_nfse_por_rps.rb +6 -0
- data/test/factories/servico/betha/v2/envio_lote_rps_sincrono.rb +5 -0
- data/test/factories/servico/betha/v2/gateway.rb +5 -0
- data/test/factories/servico/betha/v2/gera_nfse.rb +6 -0
- data/test/factories/servico/betha/v2/recepcao_lote_rps.rb +5 -0
- data/test/factories/servico/betha/v2/substituicao_nfse.rb +8 -0
- metadata +50 -17
- data/Gemfile +0 -15
- data/Rakefile +0 -13
- data/lib/br_nfe/seed.rb +0 -195
- data/lib/br_nfe/servico/betha/v2/response.rb +0 -23
- data/test/certificado.rb +0 -12
- data/test/test_helper.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d81e02350802d65933239ed64f4e46ac7f214e59
|
4
|
+
data.tar.gz: 4775126aada4c05183bdb6b1227575dff1df7f0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93b60f03c14917b7e79724be3853e3681bc88921f0e9d7b0c98463cfe8282ba8f37858354fa4b640c17e415bcde89b8e51e21981f75d79926ff8aa99f97cabba
|
7
|
+
data.tar.gz: 2341287f4bdaf2994584db7318408b1242c45683d7038be7d72f65531b7ae888ac10f6a4b5cf3b447ac7b8c1322897a16e15328f6b7ead0e0ae877f579391823
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
br_nfe (1.0.
|
4
|
+
br_nfe (1.0.1)
|
5
5
|
activemodel (~> 4.2)
|
6
6
|
activesupport (~> 4.2)
|
7
7
|
nokogiri (~> 1.6)
|
@@ -53,6 +53,8 @@ GEM
|
|
53
53
|
ansi (1.5.0)
|
54
54
|
arel (6.0.2)
|
55
55
|
builder (3.2.2)
|
56
|
+
codeclimate-test-reporter (0.4.8)
|
57
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
56
58
|
docile (1.1.5)
|
57
59
|
erubis (2.7.0)
|
58
60
|
factory_girl (4.5.0)
|
@@ -159,6 +161,7 @@ PLATFORMS
|
|
159
161
|
|
160
162
|
DEPENDENCIES
|
161
163
|
br_nfe!
|
164
|
+
codeclimate-test-reporter
|
162
165
|
factory_girl_rails
|
163
166
|
minitest-matchers_vaccine
|
164
167
|
minitest-rails
|
data/README.markdown
CHANGED
@@ -1,4 +1,266 @@
|
|
1
|
-
|
1
|
+
[](https://travis-ci.org/Brunomm/br_nfe)
|
2
|
+
[](https://codeclimate.com/github/Brunomm/br_nfe/coverage)
|
3
|
+
[](http://badge.fury.io/rb/br_nfe)
|
4
|
+
[](https://gemnasium.com/Brunomm/br_nfe)
|
5
|
+
[](https://hakiri.io/github/Brunomm/br_nfe/master)
|
6
|
+
[](https://codeclimate.com/github/Brunomm/br_nfe)
|
7
|
+
|
8
|
+
# **BrNfe**
|
9
|
+
Gem para emissão de notas fiscais eletrônicas.
|
10
|
+
|
11
|
+
## Versão 1.0.1
|
12
|
+
**Motivo e Objetivo**
|
13
|
+
Devido a falta de padronização dos parâmetros e a forma de envio e resposta na transmissão de Notas Fiscais de Serviços (NFS), esta gem vem com o objetivo de obter uma forma padronizada dessa tarefa, e assim, facilitando a vida de muitos desenvolvedores.
|
14
|
+
|
15
|
+
**O que essa gem faz?**
|
16
|
+
|
17
|
+
- Assina digitalmente a nota fiscal eletrônica.
|
18
|
+
- Envia os parâmetros com a formatação adequada conforme documentação de cada web service desenvolvido.
|
19
|
+
- Formata em um padrão único a resposta de cada web service.
|
20
|
+
- Valida (opcionalmente) a obrigatoriedade de cada informação a ser enviada.
|
21
|
+
|
22
|
+
## Instalação
|
23
|
+
**Manualmente**
|
24
|
+
|
25
|
+
gem install br_nfe
|
26
|
+
|
27
|
+
**Gemfile**
|
28
|
+
|
29
|
+
gem 'br_nfe'
|
30
|
+
|
31
|
+
## NFS-e desenvolvidas
|
32
|
+
|
33
|
+
* Betha Sistemas V 1.0
|
34
|
+
* Betha Sistemas V 2.02
|
35
|
+
|
36
|
+
####**1 - Começando**
|
37
|
+
Foi criado várias classes para auxiliar na montagem dos dados para emissão da NF, dentre eles estão:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
BrNfe::Endereco
|
41
|
+
BrNfe::Emitente
|
42
|
+
BrNfe::Destinatario
|
43
|
+
BrNfe::CondicaoPagamento
|
44
|
+
BrNfe::Servico::Intermediario
|
45
|
+
BrNfe::Servico::Rps
|
46
|
+
```
|
47
|
+
|
48
|
+
A seguir um exemplo de cada objeto com valores:
|
49
|
+
|
50
|
+
**Endereço:**
|
51
|
+
```ruby
|
52
|
+
@endereco = BrNfe::Endereco.new({
|
53
|
+
logradouro: "RUA FERNANDO MACHADO",
|
54
|
+
numero: 369,
|
55
|
+
complemento: "E",
|
56
|
+
bairro: "CENTRO",
|
57
|
+
nome_municipio: "CHAPECÓ",
|
58
|
+
codigo_municipio: 4204202,
|
59
|
+
uf: "SC",
|
60
|
+
cep: "89665-000",
|
61
|
+
# codigo_pais: 1058, <- Default
|
62
|
+
# nome_pais: 'BRASIL', <- Default
|
63
|
+
})
|
64
|
+
```
|
65
|
+
***
|
66
|
+
**Emitente:**
|
67
|
+
```ruby
|
68
|
+
@emitente = BrNfe::Emitente.new({
|
69
|
+
cnpj: '11.111.111/1111-00',
|
70
|
+
inscricao_municipal: '66165-4',
|
71
|
+
razao_social: 'RAZÃO SOCIAL',
|
72
|
+
natureza_operacao: '1',
|
73
|
+
nome_fantasia: 'NOME FANTASIA',
|
74
|
+
telefone: '4933665577',
|
75
|
+
email: 'emitente@mail.com',
|
76
|
+
regime_especial_tributacao: '1',
|
77
|
+
optante_simples_nacional: true,
|
78
|
+
incentivo_fiscal: false,
|
79
|
+
endereco: @endereco
|
80
|
+
})
|
81
|
+
```
|
82
|
+
|
83
|
+
Perceba que para definir o endereço do emitente, foi setado diretamente o objeto `@endereco`, porém, também é possível setar o objeto endereço em forma de `block` ou `hash` (isso vale para todas as classes), por exemplo:
|
84
|
+
```ruby
|
85
|
+
# Hash
|
86
|
+
@emitente = BrNfe::Emitente.new({
|
87
|
+
cnpj: '11.111.111/1111-00',
|
88
|
+
...
|
89
|
+
endereco: {
|
90
|
+
logradouro: "RUA FERNANDO MACHADO",
|
91
|
+
numero: 369,
|
92
|
+
complemento: "E",
|
93
|
+
...
|
94
|
+
}
|
95
|
+
})
|
96
|
+
# Block
|
97
|
+
@emitente = BrNfe::Emitente.new do |emitente|
|
98
|
+
emitente.cnpj = '11.111.111/1111-00'
|
99
|
+
...
|
100
|
+
emitente.endereco do |endereco|
|
101
|
+
endereco.logradouro = "RUA FERNANDO ...",
|
102
|
+
endereco.numero = 369,
|
103
|
+
endereco.complemento = "E",
|
104
|
+
...
|
105
|
+
end
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
Lembrando que por padrão, sempre que for chamar `@emitente.endereco` irá retornar um objeto da class `BrNfe::Endereco`, mesmo que não seja setado valor algum, ex:
|
110
|
+
```ruby
|
111
|
+
@emitente = BrNfe::Emitente.new
|
112
|
+
@emitente.endereco
|
113
|
+
# => #<BrNfe::Endereco:0x000000022669a0 @codigo_pais="1058", ....>
|
114
|
+
```
|
115
|
+
***
|
116
|
+
**Destinatário**
|
117
|
+
```ruby
|
118
|
+
@destinatario = BrNfe::Destinatario.new({
|
119
|
+
cpf_cnpj: "111.111.111-00",
|
120
|
+
inscricao_municipal: "",
|
121
|
+
inscricao_estadual: "",
|
122
|
+
inscricao_suframa: "",
|
123
|
+
razao_social: "NOME DA PESSOA OU EMPRESA",
|
124
|
+
nome_fantasia: "",
|
125
|
+
telefone: "3365478",
|
126
|
+
email: "destinatario@mail.com",
|
127
|
+
endereco: {
|
128
|
+
...
|
129
|
+
}
|
130
|
+
})
|
131
|
+
```
|
132
|
+
***
|
133
|
+
**Condição de pagamento**
|
134
|
+
```ruby
|
135
|
+
@condicao_pagamento = BrNfe::CondicaoPagamento.new do |cond|
|
136
|
+
cond.condicao = 'A_PRAZO' # ou 'A_VISTA'
|
137
|
+
cond.parcelas = [
|
138
|
+
{valor: 50.33, vencimento: Date.today},
|
139
|
+
{valor: '27.00', vencimento: 1.month.since}
|
140
|
+
]
|
141
|
+
end
|
142
|
+
```
|
143
|
+
***
|
144
|
+
**Intermediário do serviço**
|
145
|
+
```ruby
|
146
|
+
@intermediario = BrNfe::Servico::Intermediario.new({
|
147
|
+
cpf_cnpj: '11.111.111/0001-36',
|
148
|
+
inscricao_municipal: '3355-6',
|
149
|
+
razao_social: "INTERMEDIÁRIO DO SERVIÇO"
|
150
|
+
})
|
151
|
+
```
|
152
|
+
***
|
153
|
+
**RPS**
|
154
|
+
```ruby
|
155
|
+
@rps = BrNfe::Servico::Rps.new do |rps|
|
156
|
+
rps.destinatario = { ... } # Attributos da class BrNfe::Destinatario
|
157
|
+
rps.intermediario do |intermediario|
|
158
|
+
.... # Dados da class BrNfe::Servico::Intermediario
|
159
|
+
end
|
160
|
+
rps.condicao_pagamento = BrNfe::CondicaoPagamento.new(...)
|
161
|
+
|
162
|
+
rps.numero = 5525
|
163
|
+
rps.serie = "SN"
|
164
|
+
rps.tipo = "1"
|
165
|
+
rps.data_emissao = DateTime.now
|
166
|
+
rps.status = "1"
|
167
|
+
rps.competencia = DateTime.now
|
168
|
+
rps.numero_substituicao = "5524"
|
169
|
+
rps.serie_substituicao = "SN"
|
170
|
+
rps.tipo_substituicao = "1"
|
171
|
+
rps.codigo_obra = ""
|
172
|
+
rps.codigo_art = ""
|
173
|
+
rps.valor_servicos = 100.00
|
174
|
+
rps.valor_deducoes = "0"
|
175
|
+
rps.valor_pis = "0"
|
176
|
+
rps.valor_cofins = ""
|
177
|
+
rps.valor_inss = ""
|
178
|
+
rps.valor_ir = ""
|
179
|
+
rps.valor_csll = ""
|
180
|
+
rps.outras_retencoes = ""
|
181
|
+
rps.iss_retido = ""
|
182
|
+
rps.valor_iss = 2.0
|
183
|
+
rps.aliquota = 0.02 # = 2%
|
184
|
+
rps.base_calculo = "100.00"
|
185
|
+
rps.desconto_incondicionado = ""
|
186
|
+
rps.desconto_condicionado = ""
|
187
|
+
rps.responsavel_retencao = ""
|
188
|
+
rps.item_lista_servico = "1.07"
|
189
|
+
rps.discriminacao = "1 Configuração de servidor: R$ 500.00"
|
190
|
+
rps.exigibilidade_iss = "1"
|
191
|
+
rps.codigo_municipio = "4204202"
|
192
|
+
rps.municipio_incidencia = "4204202"
|
193
|
+
rps.codigo_pais = ""
|
194
|
+
rps.numero_processo = ""
|
195
|
+
rps.codigo_cnae = ""
|
196
|
+
rps.outras_informacoes = ""
|
197
|
+
rps.codigo_tributacao_municipio = ""
|
198
|
+
end
|
199
|
+
```
|
200
|
+
####**2 - Exemplos**
|
201
|
+
Para todos os Web Services, após instanciados, poderá ser chamado o método `request`, no qual será enviado os dados via XML para o órgão emissor correspondente.
|
202
|
+
|
203
|
+
Se desejar, antes de enviar os dados, o objeto poderá ser validado, EX:
|
204
|
+
```ruby
|
205
|
+
@ws = BrNfe::Servico::Betha::V1::ConsultaLoteRps.new(...)
|
206
|
+
if @ws.valid?
|
207
|
+
@ws.request
|
208
|
+
@response = @ws.response
|
209
|
+
end
|
210
|
+
```
|
211
|
+
O resultado obtido na variável `@response` é um objeto da class `BrNfe::Servico::Response::Default`, no qual será retornada em todas as requisições. Essa classe é responsável de manter o padrão das mensagens de resposta para todos os webservices. Se desejar, poderá obter a resposta original (no formato Hash) de cada órgão emissor através do método `original_response`.
|
212
|
+
Para saber quais os valores obtidos pelo `BrNfe::Servico::Response::Default`, veja: [Resposta padrão](exemplos/resposta_padrao.markdown)
|
213
|
+
|
214
|
+
Lista de exemplos:
|
215
|
+
|
216
|
+
* [Betha Sistemas v1.0](exemplos/betha_v1.markdown)
|
217
|
+
* [Betha Sistemas v2.02](exemplos/betha_v2.markdown)
|
218
|
+
|
219
|
+
####**3 - Configurações**
|
220
|
+
```ruby
|
221
|
+
BrNfe.setup do |config|
|
222
|
+
# É possível customizar as classes auxiliares, por exemlo,
|
223
|
+
# se você quiser fazer alguma validação específica para o endereço,
|
224
|
+
# que contenha os mesmo atributos, e setar na configuração da gem
|
225
|
+
# qual será a classe que irá representar o endereco.
|
226
|
+
# config.endereco_class = ClasseCustomizadaEndereco
|
227
|
+
|
228
|
+
config.endereco_class = BrNfe::Endereco
|
229
|
+
config.emitente_class = BrNfe::Emitente
|
230
|
+
config.destinatario_class = BrNfe::Destinatario
|
231
|
+
config.intermediario_class = BrNfe::Servico::Intermediario
|
232
|
+
config.condicao_pagamento_class = BrNfe::CondicaoPagamento
|
233
|
+
config.rps_class BrNfe::Servico::Rps
|
234
|
+
|
235
|
+
# Se você utiliza certificado SSL, faça as seguintes modificações na configuração:
|
236
|
+
# config.client_wsdl_ssl_verify_mode = :peer
|
237
|
+
# config.client_wsdl_ssl_cert_file = 'caminho/client_cert.pem'
|
238
|
+
# config.client_wsdl_ssl_cert_key_file = 'caminho/client_key.pem'
|
239
|
+
# config.client_wsdl_ssl_cert_key_password = 'senha'
|
240
|
+
config.client_wsdl_ssl_verify_mode = :none
|
241
|
+
config.client_wsdl_ssl_cert_file = nil
|
242
|
+
config.client_wsdl_ssl_cert_key_file = nil
|
243
|
+
config.client_wsdl_ssl_cert_key_password = nil
|
244
|
+
|
245
|
+
# Se você quiser exibir em log a requisição SOAP, mude para true as opções a seguir
|
246
|
+
config.client_wsdl_log = false
|
247
|
+
config.client_wsdl_pretty_print_xml = false
|
248
|
+
end
|
249
|
+
```
|
250
|
+
|
251
|
+
|
252
|
+
## Objetivos futuros
|
253
|
+
* Emitir notas fiscais de produtos.
|
254
|
+
* Emitir notas fiscais de serviços para todas as cidades do Brasil.
|
255
|
+
|
256
|
+
## Contribuições
|
257
|
+
|
258
|
+
Seja um contribuidor. Você pode contribuir de N formas. Seguem elas:
|
259
|
+
|
260
|
+
* Desenvolver emissão de NFS-e para outras cidades.
|
261
|
+
* Desenvolver emissão de NF-e (produtos).
|
262
|
+
* Refatorando código.
|
263
|
+
* Fornecendo Feedback construtivo (Sempre bem vindo!).
|
2
264
|
|
3
265
|
## Licença
|
4
266
|
|
data/br_nfe.gemspec
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
require File.expand_path('../lib/br_nfe/version', __FILE__)
|
3
3
|
|
4
|
-
Gem::Specification.new do |gem|
|
4
|
+
e = Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Bruno M. Mergen"]
|
6
6
|
gem.email = ["brunomergen@gmail.com"]
|
7
7
|
gem.description = %q{Emissão de Notas Fiscais Eletrônicas em Ruby}
|
8
|
-
gem.summary = %q{
|
8
|
+
gem.summary = %q{BrNfe é uma gem para projetos Ruby on Rails que tem como objetifo facilitar e padronizar a emissão de Notas Fiscais eletrônicas}
|
9
9
|
gem.homepage = "https://github.com/Brunomm/br_nfe"
|
10
10
|
gem.license = "BSD"
|
11
11
|
|
12
|
-
gem.files = `git ls-files`.split($\).reject
|
12
|
+
gem.files = `git ls-files`.split($\).reject do |file|
|
13
|
+
file =~ %r{^(?:
|
14
|
+
test/.*
|
15
|
+
|Gemfile
|
16
|
+
|Rakefile
|
17
|
+
|coverage/.*
|
18
|
+
|exemplos/.*
|
19
|
+
|\.travis.yml
|
20
|
+
)$}x
|
21
|
+
end
|
13
22
|
gem.test_files = `git ls-files -- test/**/*`.split("\n")
|
14
23
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
15
24
|
gem.name = "br_nfe"
|
@@ -18,11 +27,11 @@ Gem::Specification.new do |gem|
|
|
18
27
|
|
19
28
|
gem.required_ruby_version = '>= 2.1'
|
20
29
|
|
21
|
-
gem.add_dependency "rake", '
|
30
|
+
gem.add_dependency "rake", '~> 10'
|
22
31
|
gem.add_dependency "activesupport", '~> 4.2'
|
23
32
|
gem.add_dependency "activemodel", '~> 4.2'
|
24
33
|
gem.add_dependency "nokogiri", "~> 1.6"
|
25
34
|
gem.add_dependency "savon", "~> 2.11"
|
26
|
-
gem.add_dependency "signer"
|
35
|
+
gem.add_dependency "signer", "~> 1.4"
|
27
36
|
|
28
37
|
end
|
data/lib/br_nfe/base.rb
CHANGED
@@ -27,6 +27,11 @@ module BrNfe
|
|
27
27
|
@env ||= :production
|
28
28
|
end
|
29
29
|
|
30
|
+
def original_response
|
31
|
+
@original_response
|
32
|
+
end
|
33
|
+
|
34
|
+
|
30
35
|
def response
|
31
36
|
@response
|
32
37
|
end
|
@@ -160,7 +165,7 @@ module BrNfe
|
|
160
165
|
|
161
166
|
def validar_emitente
|
162
167
|
if emitente.invalid?
|
163
|
-
emitente.errors.full_messages.map{|msg| errors.add(:
|
168
|
+
emitente.errors.full_messages.map{|msg| errors.add(:base, "Emitente: #{msg}") }
|
164
169
|
end
|
165
170
|
end
|
166
171
|
|
@@ -18,11 +18,6 @@ module BrNfe
|
|
18
18
|
sem_formatacao.size > 11 ? :cnpj : :cpf
|
19
19
|
end
|
20
20
|
|
21
|
-
def tipo_documento(tamanho = 2)
|
22
|
-
return '0' if sem_formatacao.blank?
|
23
|
-
sem_formatacao.size < 14 ? '1'.rjust(tamanho, '0') : '2'.rjust(tamanho, '0')
|
24
|
-
end
|
25
|
-
|
26
21
|
def sem_formatacao
|
27
22
|
@cpf_cnpj.gsub(/[\.]|[\-]|[\/]/,'')
|
28
23
|
end
|
@@ -21,6 +21,13 @@ module BrNfe
|
|
21
21
|
rps.errors.full_messages.map{|msg| errors.add(:rps, msg) }
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
def valida_rps_recepcao
|
26
|
+
rps.validar_recepcao_rps = true
|
27
|
+
if rps.invalid?
|
28
|
+
rps.errors.full_messages.map{|msg| errors.add(:base, "RPS: #{msg}") }
|
29
|
+
end
|
30
|
+
end
|
24
31
|
|
25
32
|
end
|
26
33
|
end
|
@@ -8,17 +8,21 @@ module BrNfe
|
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def xml_identificacao_rps(rps)
|
12
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
13
|
+
xml.IdentificacaoRps {
|
14
|
+
dados_identificacao_rps(xml, rps)
|
15
|
+
}
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
|
-
def
|
18
|
-
return unless rps.contem_substituicao?
|
19
|
-
xml
|
20
|
-
|
21
|
-
|
19
|
+
def xml_rps_substituido(rps)
|
20
|
+
return Nokogiri::XML::Builder.new unless rps.contem_substituicao?
|
21
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
22
|
+
xml.RpsSubstituido {
|
23
|
+
dados_identificacao_rps(xml, rps, true)
|
24
|
+
}
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
def dados_identificacao_rps(xml, rps, substituicao = false)
|
@@ -27,45 +31,52 @@ module BrNfe
|
|
27
31
|
xml.Tipo "#{(substituicao ? rps.tipo_substituicao : rps.tipo)}".max_size(1)
|
28
32
|
end
|
29
33
|
|
30
|
-
def
|
31
|
-
xml
|
32
|
-
xml.
|
33
|
-
xml.
|
34
|
-
|
34
|
+
def xml_dados_tomador(destinatario)
|
35
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
36
|
+
xml.Tomador{
|
37
|
+
xml.IdentificacaoTomador {
|
38
|
+
xml.CpfCnpj {
|
39
|
+
tag_cpf_cnpj(xml, destinatario.cpf_cnpj)
|
40
|
+
}
|
41
|
+
xml.InscricaoMunicipal "#{destinatario.inscricao_municipal}".max_size(15) if destinatario.inscricao_municipal.present?
|
42
|
+
xml.InscricaoEstadual "#{destinatario.inscricao_estadual}".max_size(15) if destinatario.inscricao_estadual.present? && version == :v1
|
35
43
|
}
|
36
|
-
xml.
|
37
|
-
xml.InscricaoEstadual "#{destinatario.inscricao_estadual}".max_size(15) if destinatario.inscricao_estadual.present? && version == :v1
|
38
|
-
}
|
39
|
-
xml.RazaoSocial "#{destinatario.razao_social}".max_size(115)
|
44
|
+
xml.RazaoSocial "#{destinatario.razao_social}".max_size(115)
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
xml.
|
45
|
-
|
46
|
+
# endereço
|
47
|
+
xml.__send__ :insert, Nokogiri::XML::DocumentFragment.parse( xml_endereco(destinatario.endereco).doc.root.to_s )
|
48
|
+
|
49
|
+
xml.Contato {
|
50
|
+
xml.Telefone BrNfe::Helper.only_number(destinatario.telefone).max_size(11) unless destinatario.telefone.blank?
|
51
|
+
xml.Email "#{destinatario.email}".max_size(80) unless destinatario.email.blank?
|
52
|
+
}
|
46
53
|
}
|
47
|
-
|
54
|
+
end
|
48
55
|
end
|
49
56
|
|
50
|
-
def
|
51
|
-
|
52
|
-
xml.Endereco
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
def xml_endereco(endereco, cod_pais=false)
|
58
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
59
|
+
xml.Endereco {
|
60
|
+
xml.Endereco "#{endereco.logradouro}".max_size(125)
|
61
|
+
xml.Numero "#{endereco.numero}".max_size(10)
|
62
|
+
xml.Complemento "#{endereco.complemento}".max_size(60)
|
63
|
+
xml.Bairro "#{endereco.bairro}".max_size(60)
|
64
|
+
xml.CodigoMunicipio BrNfe::Helper.only_number(endereco.codigo_municipio).max_size(7)
|
65
|
+
xml.Uf "#{endereco.uf}".max_size(2)
|
66
|
+
xml.Cep BrNfe::Helper.only_number(endereco.cep).max_size(8)
|
67
|
+
xml.CodigoPais BrNfe::Helper.only_number(endereco.codigo_pais).max_size(4) if version == :v2 && cod_pais
|
68
|
+
}
|
69
|
+
end
|
61
70
|
end
|
62
71
|
|
63
|
-
def
|
64
|
-
return if rps.codigo_obra.blank? || rps.codigo_art.blank?
|
65
|
-
xml
|
66
|
-
xml.
|
67
|
-
|
68
|
-
|
72
|
+
def xml_dados_construcao_civil(rps)
|
73
|
+
return Nokogiri::XML::Builder.new if rps.codigo_obra.blank? || rps.codigo_art.blank?
|
74
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
75
|
+
xml.ConstrucaoCivil{
|
76
|
+
xml.CodigoObra "#{rps.codigo_obra}".max_size(15)
|
77
|
+
xml.Art "#{rps.codigo_art}".max_size(15)
|
78
|
+
}
|
79
|
+
end
|
69
80
|
end
|
70
81
|
|
71
82
|
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module BrNfe
|
2
|
+
module Servico
|
3
|
+
module Betha
|
4
|
+
class BuildResponse < BrNfe::ActiveModelBase
|
5
|
+
attr_accessor :nfe_method
|
6
|
+
|
7
|
+
def initialize(attributes = {})
|
8
|
+
@error_messages = []
|
9
|
+
super(attributes)
|
10
|
+
end
|
11
|
+
|
12
|
+
def success?
|
13
|
+
error_messages.blank?
|
14
|
+
end
|
15
|
+
|
16
|
+
def response
|
17
|
+
@response ||= BrNfe::Servico::Response::Default.new do |resp|
|
18
|
+
resp.success = success?
|
19
|
+
resp.error_messages = error_messages
|
20
|
+
resp.notas_fiscais = get_notas_fiscais
|
21
|
+
resp.protocolo = messages[:protocolo]
|
22
|
+
resp.data_recebimento = messages[:data_recebimento]
|
23
|
+
resp.numero_lote = messages[:numero_lote]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def error_messages
|
28
|
+
return @error_messages unless @error_messages.blank?
|
29
|
+
|
30
|
+
get_messages!(messages[:lista_nfse][:listamensagem_alerta_retorno]) if messages[:lista_nfse]
|
31
|
+
get_messages!(messages[:lista_mensagem_retorno])
|
32
|
+
get_messages!(messages[:lista_mensagem_retorno_lote])
|
33
|
+
|
34
|
+
@error_messages
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def get_notas_fiscais
|
40
|
+
@notas_fiscais = []
|
41
|
+
return @notas_fiscais if messages[:lista_nfse].blank? || messages[:lista_nfse][key_complemento_nfse].blank?
|
42
|
+
comp_nfse = messages[:lista_nfse][key_complemento_nfse]
|
43
|
+
|
44
|
+
if comp_nfse.is_a?(Hash)
|
45
|
+
@notas_fiscais << new_nota_fiscal(comp_nfse)
|
46
|
+
elsif comp_nfse.is_a?(Array)
|
47
|
+
comp_nfse.map{|p| @notas_fiscais << new_nota_fiscal(p) }
|
48
|
+
end
|
49
|
+
@notas_fiscais
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_messages!(msgs)
|
53
|
+
return unless msgs
|
54
|
+
msgs = msgs[:mensagem_retorno]
|
55
|
+
if msgs.is_a?(Hash)
|
56
|
+
@error_messages << get_message(msgs)
|
57
|
+
elsif msgs.is_a?(Array)
|
58
|
+
msgs.each do |msg|
|
59
|
+
@error_messages << get_message(msg)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_message(hash)
|
65
|
+
if hash[:identificacao_rps]
|
66
|
+
{
|
67
|
+
codigo: hash[:codigo],
|
68
|
+
mensagem: hash[:mensagem],
|
69
|
+
rps: {
|
70
|
+
numero: hash[:identificacao_rps][:numero],
|
71
|
+
serie: hash[:identificacao_rps][:serie],
|
72
|
+
tipo: hash[:identificacao_rps][:tipo],
|
73
|
+
}
|
74
|
+
}
|
75
|
+
else
|
76
|
+
{
|
77
|
+
codigo: hash[:codigo],
|
78
|
+
mensagem: hash[:mensagem],
|
79
|
+
correcao: hash[:correcao]
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_construcao_civil(nfse, params)
|
85
|
+
params ||= {}
|
86
|
+
nfse.codigo_obra = params[:codigo_obra]
|
87
|
+
nfse.codigo_art = params[:art]
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_info_substituicao(nfse, params)
|
91
|
+
params ||= {}
|
92
|
+
params = params[:substituicao_nfse] || {}
|
93
|
+
|
94
|
+
nfse.nfe_substituidora = params[:nfse_substituidora]
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def get_orgao_gerador(nfse, params)
|
99
|
+
params ||= {}
|
100
|
+
nfse.orgao_gerador_municipio = params[:codigo_municipio]
|
101
|
+
nfse.orgao_gerador_uf = params[:uf]
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_destinatario_servico(nfse, params)
|
105
|
+
params ||= {}
|
106
|
+
nfse.destinatario do |dest|
|
107
|
+
if identificacao = params[:identificacao_tomador]
|
108
|
+
dest.cpf_cnpj = identificacao[:cpf_cnpj][:cnpj] || identificacao[:cpf_cnpj][:cpf] if identificacao[:cpf_cnpj]
|
109
|
+
dest.inscricao_municipal = identificacao[:inscricao_municipal]
|
110
|
+
dest.inscricao_estadual = identificacao[:inscricao_estadual]
|
111
|
+
end
|
112
|
+
dest.razao_social = params[:razao_social]
|
113
|
+
dest.nome_fantasia = params[:nome_fantasia]
|
114
|
+
if params[:contato]
|
115
|
+
dest.telefone = params[:contato][:telefone]
|
116
|
+
dest.email = params[:contato][:email]
|
117
|
+
end
|
118
|
+
dest.endereco = get_endereco(params[:endereco])
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def get_endereco(params)
|
124
|
+
params ||= {}
|
125
|
+
BrNfe::Endereco.new do |e|
|
126
|
+
e.logradouro = params[:endereco]
|
127
|
+
e.numero = params[:numero]
|
128
|
+
e.complemento = params[:complemento]
|
129
|
+
e.bairro = params[:bairro]
|
130
|
+
e.nome_municipio = params[:nome_municipio]
|
131
|
+
e.codigo_municipio = params[:codigo_municipio]
|
132
|
+
e.uf = params[:uf]
|
133
|
+
e.cep = params[:cep]
|
134
|
+
e.codigo_pais = params[:codigo_pais] if params[:codigo_pais]
|
135
|
+
e.nome_pais = params[:nome_pais] if params[:nome_pais]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|