br_nfe 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/Brunomm/br_nfe.svg?branch=master)](https://travis-ci.org/Brunomm/br_nfe)
|
2
|
+
[![Test Coverage](https://codeclimate.com/github/Brunomm/br_nfe/badges/coverage.svg)](https://codeclimate.com/github/Brunomm/br_nfe/coverage)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/br_nfe.svg)](http://badge.fury.io/rb/br_nfe)
|
4
|
+
[![Dependency Status](https://gemnasium.com/Brunomm/br_nfe.svg)](https://gemnasium.com/Brunomm/br_nfe)
|
5
|
+
[![security](https://hakiri.io/github/Brunomm/br_nfe/master.svg)](https://hakiri.io/github/Brunomm/br_nfe/master)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/Brunomm/br_nfe/badges/gpa.svg)](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
|