brcobranca 5.0.1 → 5.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f207e4ab5343d33ec1bd49dd3855887684f7e5be
4
- data.tar.gz: 58b0eb4d58eab09ef07e780a7d514ada237a6b08
3
+ metadata.gz: f5751e9101d0cf0eb85bab01fd288d9dff981fd5
4
+ data.tar.gz: abff42b7d529d2963ecf006f816f48bc7182d37e
5
5
  SHA512:
6
- metadata.gz: c5ef2a9c880d5365a08613a4b58b1102b7b7e56dd5e81885297efa1c9ca9f17347a56593ec882c1945d952008b22ec5302960b74c9068a231ed8bbe245b296fb
7
- data.tar.gz: 141d9c780794cde4c49d753eb8e0667493642aa10b86e9ab66282c18626aad16d25ad0ddf8f2d352aa3d08f0b8f0f3838bcea8cb94ae7bd25ad0cfa05fa73df0
6
+ metadata.gz: b779e57b2fc1dfd0250b637fc6d10833ee01744f9124f41c6915107107ea1715b53be33c7963fce7335b240125d431a0ee9cbf5950b0781ff30d5264e21d8255
7
+ data.tar.gz: d38b0e866f9f97c05635adc4abe4817e39501d0e7a866fc952e1fcb19517f04e7bebf49f35e1e9f5fc787ec6d31a3a0cc2a36bd6ecdde92e786b168fef5d955b
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.2.3
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - '2.2.2'
3
+ - '2.2.3'
4
4
  - '2.1.6'
5
5
  - '2.0.0'
6
6
  - '1.9.3'
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ gemspec
5
5
 
6
6
  group :development do
7
7
  gem 'pry', '~> 0.10.0'
8
- gem 'rubocop', '~> 0.32.1'
8
+ gem 'rubocop', '~> 0.34.1'
9
9
  gem 'rubocop-rspec', '~> 1.3.0'
10
10
  end
11
11
 
data/README.md CHANGED
@@ -20,30 +20,16 @@ Gem para emissão de bloquetos de cobrança para bancos brasileiros.
20
20
 
21
21
  ### Bancos Disponíveis
22
22
 
23
- * Banco do Brasil
24
- * Todas as carteiras presentes na documentação
25
-
26
- * Banco Itaú
27
- * Todas as carteiras presentes na documentação
28
-
29
- * Banco HSBC
30
- * CNR
31
- * CSB - [Rafael DL](https://github.com/rafaeldl)
32
-
33
- * Banco Bradesco
34
- * Todas as carteiras presentes na documentação
35
-
36
- * Banco Caixa
37
- * Sem registro - [Túlio Ornelas](https://github.com/tulios)
38
-
39
- * Banco SICREDI
40
-
41
- * Banco Santander - [Ronaldo Araujo](https://github.com/ronaldoaraujo)
42
- * Sem registro
43
- * Com registro
44
-
45
- * Banco Sicoob
46
- * Todas as carteiras presentes na documentação
23
+ | Bancos | Carteiras | Documentações |
24
+ |-----------------------|-------------------|----------------|
25
+ | 001 - Banco do Brasil | Todas as carteiras presentes na documentação | [pdf](http://www.bb.com.br/docs/pub/emp/empl/dwn/Doc5175Bloqueto.pdf) |
26
+ | 033 - Santander | Sem registro, Com registro - [Ronaldo Araujo](https://github.com/ronaldoaraujo) | [pdf](http://177.69.143.161:81/Treinamento/SisMoura/Documentação%20Boleto%20Remessa/Documentacao_SANTANDER/Layout%20de%20Cobrança%20-%20Código%20de%20Barras%20Santander%20Setembro%202012%20v%202%203.pdf) |
27
+ | 104 - Caixa | Sem registro - [Túlio Ornelas](https://github.com/tulios) | [pdf](http://downloads.caixa.gov.br/_arquivos/cobranca_caixa_sigcb/manuais/CODIGO_BARRAS_SIGCB.PDF) |
28
+ | 237 - Bradesco | Todas as carteiras presentes na documentação | [pdf](http://www.bradesco.com.br/portal/PDF/pessoajuridica/solucoes-integradas/outros/layout-de-arquivo/cobranca/4008-524-0121-08-layout-cobranca-versao-portugues.pdf) |
29
+ | 341 - Itaú | Todas as carteiras presentes na documentação | [CNAB240](http://download.itau.com.br/bankline/cobranca_cnab240.pdf), [CNAB400](http://download.itau.com.br/bankline/layout_cobranca_400bytes_cnab_itau_mensagem.pdf) |
30
+ | 399 - HSBC | CNR, CSB - [Rafael DL](https://github.com/rafaeldl) | |
31
+ | 748 - Sicredi | C (03) | |
32
+ | 756 - Sicoob | Todas as carteiras presentes na documentação | |
47
33
 
48
34
  ### Retornos Disponíveis
49
35
 
data/lib/brcobranca.rb CHANGED
@@ -133,6 +133,7 @@ module Brcobranca
133
133
  autoload :Bradesco, 'brcobranca/remessa/cnab400/bradesco'
134
134
  autoload :Itau, 'brcobranca/remessa/cnab400/itau'
135
135
  autoload :Citibank, 'brcobranca/remessa/cnab400/citibank'
136
+ autoload :Santander, 'brcobranca/remessa/cnab400/santander'
136
137
  end
137
138
 
138
139
  module Cnab240
@@ -4,7 +4,7 @@ module Brcobranca
4
4
  class Sicoob < Base # Sicoob (Bancoob)
5
5
  validates_length_of :agencia, maximum: 4, message: "deve ser menor ou igual a 4 dígitos."
6
6
  validates_length_of :conta_corrente, maximum: 8, message: "deve ser menor ou igual a 8 dígitos."
7
- validates_length_of :numero_documento, maximum: 6, message: "deve ser menor ou igual a 6 dígitos."
7
+ validates_length_of :numero_documento, maximum: 7, message: "deve ser menor ou igual a 7 dígitos."
8
8
 
9
9
  def initialize(campos = {})
10
10
  campos = { carteira: "1" }.merge!(campos)
@@ -42,16 +42,29 @@ module Brcobranca
42
42
 
43
43
  # Número documento
44
44
  #
45
- # @return [String] 6 caracteres numéricos.
45
+ # @return [String] 7 caracteres numéricos.
46
46
  def numero_documento=(valor)
47
- @numero_documento = valor.to_s.rjust(6, "0") if valor
47
+ @numero_documento = valor.to_s.rjust(7, "0") if valor
48
48
  end
49
49
 
50
50
  # Nosso número para exibição no boleto.
51
51
  #
52
52
  # @return [String] 8 caracteres numéricos.
53
53
  def nosso_numero_boleto
54
- "#{Date.today.strftime("%y")}#{numero_documento}"
54
+ "#{numero_documento}#{nosso_numero_dv}"
55
+ end
56
+
57
+ # DV do nosso número seguindo o manual da sicoob
58
+ # http://www.bancoob.com.br/atendimentocobranca/CAS/2_Implantação_do_Serviço/Sistema_Proprio/DigitoVerificador.htm
59
+ #
60
+ # Os dígitos multiplicadores presentes na documentação da sicoob estão em ordem diferente da ordem abaixo
61
+ # devido ao cálculo em ordem inversa em Brcobranca::Calculo pelo método `multiplicador`.
62
+ #
63
+ def nosso_numero_dv
64
+ "#{agencia}#{convenio}#{numero_documento}".modulo11(
65
+ multiplicador: [3, 7, 9, 1],
66
+ mapeamento: { 10 => 0, 11 => 0 }
67
+ ) { |t| 11 - (t % 11) }
55
68
  end
56
69
 
57
70
  # Modalidade de cobrança
@@ -12,16 +12,16 @@ module Brcobranca
12
12
 
13
13
  validates_presence_of :carteira, :variacao, message: 'não pode estar em branco.'
14
14
  validates_presence_of :convenio, message: 'não pode estar em branco.'
15
- validates_length_of :conta_corrente, is: 5, message: 'deve ter 5 dígitos.'
16
- validates_length_of :agencia, is: 4, message: 'deve ter 4 dígitos.'
15
+ validates_length_of :conta_corrente, maximum: 12, message: 'deve ter 12 dígitos.'
16
+ validates_length_of :agencia, maximum: 5, message: 'deve ter 5 dígitos.'
17
17
  validates_length_of :carteira, is: 2, message: 'deve ter 2 dígitos.'
18
18
  validates_length_of :variacao, is: 3, message: 'deve ter 3 dígitos.'
19
19
  validates_length_of :convenio, in: 4..7, message: 'não existente para este banco.'
20
20
 
21
21
  def initialize(campos = {})
22
22
  campos = { emissao_boleto: '0',
23
- distribuicao_boleto: '0',
24
- especie_titulo: '02' }.merge!(campos)
23
+ distribuicao_boleto: '0',
24
+ especie_titulo: '02' }.merge!(campos)
25
25
  super(campos)
26
26
  end
27
27
 
@@ -62,6 +62,7 @@ module Brcobranca
62
62
  # campo reservado 2
63
63
  "#{convenio.rjust(9, '0')}0014#{carteira}#{variacao} "
64
64
  end
65
+
65
66
  alias_method :convenio_lote, :codigo_convenio
66
67
 
67
68
  def info_conta
@@ -98,11 +99,14 @@ module Brcobranca
98
99
  def formata_nosso_numero(nosso_numero)
99
100
  quantidade = case convenio.to_s.size
100
101
  # convenio de 4 posicoes com nosso numero de 7
101
- when 4 then 7
102
+ when 4 then
103
+ 7
102
104
  # convenio de 6 posicoes com nosso numero de 5
103
- when 6 then 5
105
+ when 6 then
106
+ 5
104
107
  # convenio de 7 posicoes com nosso numero de 10
105
- when 7 then 10
108
+ when 7 then
109
+ 10
106
110
  else
107
111
  fail Brcobranca::NaoImplementado.new('Tipo de convênio não implementado.')
108
112
  end
@@ -42,7 +42,7 @@ module Brcobranca
42
42
  def initialize(campos = {})
43
43
  campos = { codigo_carteira: '1',
44
44
  forma_cadastramento: '1',
45
- tipo_documento: ' '}.merge!(campos)
45
+ tipo_documento: ' ' }.merge!(campos)
46
46
  super(campos)
47
47
  end
48
48
 
@@ -59,7 +59,7 @@ module Brcobranca
59
59
  # @return [String]
60
60
  #
61
61
  def hora_geracao
62
- Time.now.strftime('%H%M%S')
62
+ (Time.respond_to?(:current) ? Time.current : Time.now).strftime('%H%M%S')
63
63
  end
64
64
 
65
65
  # Monta o registro header do arquivo
@@ -267,19 +267,21 @@ module Brcobranca
267
267
  #
268
268
  # @return [Array]
269
269
  #
270
- def monta_lote(pagamento, nro_lote)
271
- fail Brcobranca::RemessaInvalida.new(pagamento) if pagamento.invalid?
272
-
270
+ def monta_lote(nro_lote)
273
271
  # contador dos registros do lote
274
- contador = 1
272
+ contador = 1 #header
275
273
 
276
274
  lote = [monta_header_lote(nro_lote)]
277
275
 
278
- lote << monta_segmento_p(pagamento, nro_lote, contador)
279
- contador += 1
276
+ pagamentos.each do |pagamento|
277
+ fail Brcobranca::RemessaInvalida.new(pagamento) if pagamento.invalid?
280
278
 
281
- lote << monta_segmento_q(pagamento, nro_lote, contador)
282
- contador += 2 #header + trailer
279
+ lote << monta_segmento_p(pagamento, nro_lote, contador)
280
+ contador += 1
281
+ lote << monta_segmento_q(pagamento, nro_lote, contador)
282
+ contador += 1
283
+ end
284
+ contador += 1 #trailer
283
285
 
284
286
  lote << monta_trailer_lote(nro_lote, contador)
285
287
 
@@ -293,17 +295,14 @@ module Brcobranca
293
295
  def gera_arquivo
294
296
  fail Brcobranca::RemessaInvalida.new(self) if self.invalid?
295
297
 
296
- # contador de do lotes
297
- contador = 1
298
-
299
298
  arquivo = [monta_header_arquivo]
300
299
 
301
- pagamentos.each do |pagamento|
302
- novo_lote = monta_lote(pagamento, contador)
303
- arquivo.push novo_lote
304
- end
300
+ # contador de do lotes
301
+ contador = 1
302
+ novo_lote = monta_lote(contador)
303
+ arquivo.push novo_lote
305
304
 
306
- arquivo << monta_trailer_arquivo(contador, (arquivo.size + (pagamentos.size * 4)))
305
+ arquivo << monta_trailer_arquivo(contador, ((pagamentos.size * 2) + (contador * 2) + 2))
307
306
 
308
307
  remessa = arquivo.join("\n")
309
308
  remessa
@@ -26,7 +26,9 @@ module Brcobranca
26
26
  # Parcela - 02 posições (11 a 12) - "01" se parcela única
27
27
 
28
28
  validates_presence_of :modalidade_carteira, :tipo_formulario, :parcela, message: 'não pode estar em branco.'
29
- validates_length_of :conta_corrente, is: 5, message: 'deve ter 5 dígitos.'
29
+ # Remessa 400 - 8 digitos
30
+ # Remessa 240 - 12 digitos
31
+ validates_length_of :conta_corrente, maximum: 8, message: 'deve ter 8 dígitos.'
30
32
  validates_length_of :agencia, is: 4, message: 'deve ter 4 dígitos.'
31
33
  validates_length_of :modalidade_carteira, is: 2, message: 'deve ter 2 dígitos.'
32
34
 
@@ -23,6 +23,7 @@ module Brcobranca
23
23
  # tipo do registro [1] 0
24
24
  # operacao [1] 1
25
25
  # literal remessa [7] REMESSA
26
+ # Código do serviço [2] 01
26
27
  # cod. servico [15] COBRANCA
27
28
  # info. conta [20]
28
29
  # empresa mae [30]
@@ -97,8 +97,8 @@ module Brcobranca
97
97
  detalhe << ' ' # indicador rateio X[01] 105 a 105
98
98
  detalhe << '2' # endereco para aviso debito (op 2 = ignora) 9[01] 106 a 106
99
99
  detalhe << ''.rjust(2, ' ') # brancos X[02] 107 a 108
100
- detalhe << '01' # identif. da ocorrencia 9[02] 109 a 110
101
- detalhe << pagamento.nosso_numero.to_s.rjust(10, ' ') # numero do documento alfanum. X[10] 111 a 120
100
+ detalhe << pagamento.identificacao_ocorrencia # identificacao ocorrencia 9[02]
101
+ detalhe << pagamento.numero_documento.to_s.rjust(10, ' ') # numero do documento alfanum. X[10] 111 a 120
102
102
  detalhe << pagamento.data_vencimento.strftime('%d%m%y') # data de vencimento 9[06] 121 a 126
103
103
  detalhe << pagamento.formata_valor # valor do titulo 9[13] 127 a 139
104
104
  detalhe << ''.rjust(3, '0') # banco encarregado (zeros) 9[03] 140 a 142
@@ -67,7 +67,7 @@ module Brcobranca
67
67
  detalhe << documento_cedente.to_s.rjust(14, '0') # cpf/cnpj da empresa 9[14]
68
68
  detalhe << portfolio # portfolio X[20]
69
69
  detalhe << ''.rjust(25, ' ') # identificacao do tit. na empresa X[25]
70
- detalhe << '02' # espécie do título 9[02] - 00 = DMI – Duplicata Mercantil por Indicação, 02 = DM – Duplicata Mercantil
70
+ detalhe << pagamento.especie_titulo # espécie do título 9[02] - 00 = DMI – Duplicata Mercantil por Indicação, 02 = DM – Duplicata Mercantil
71
71
  detalhe << pagamento.nosso_numero.to_s.rjust(12, '0') # nosso numero 9[12]
72
72
  detalhe << ''.rjust(6, ' ') # brancos X[06]
73
73
  detalhe << pagamento.formata_data_segundo_desconto # data limite para o segundo desconto 9[06]
@@ -75,8 +75,8 @@ module Brcobranca
75
75
  detalhe << '000' # carne 9[03] - Válido apenas quando o campo 148/149 for igual a 03
76
76
  detalhe << '000' # parcela 9[03] - Só preencher se o banco for imprimir e enviar e for um carnê
77
77
  detalhe << carteira # codigo da carteira X[01] - Código 1 = Cobrança Simples, Código 2 = Cobrança Caucionada
78
- detalhe << '01' # identificacao ocorrencia (remessa) 9[02]
79
- detalhe << pagamento.nosso_numero.to_s.rjust(10, '0') # numero do documento X[10]
78
+ detalhe << pagamento.identificacao_ocorrencia # identificacao ocorrencia 9[02]
79
+ detalhe << pagamento.numero_documento.to_s.rjust(10, '0') # numero do documento X[10]
80
80
  detalhe << pagamento.data_vencimento.strftime('%d%m%y') # data do vencimento 9[06]
81
81
  detalhe << pagamento.formata_valor # valor do documento 9[13]
82
82
  detalhe << cod_banco # codigo banco 9[03]
@@ -50,7 +50,7 @@ module Brcobranca
50
50
  # complemento 2
51
51
  # conta corrente 5
52
52
  # digito da conta 1
53
- # complemento 8\
53
+ # complemento 8
54
54
  "#{agencia}00#{conta_corrente}#{digito_conta}#{''.rjust(8, ' ')}"
55
55
  end
56
56
 
@@ -103,17 +103,17 @@ module Brcobranca
103
103
  detalhe << carteira # carteira 9[03]
104
104
  detalhe << ''.rjust(21, ' ') # identificacao da operacao no banco X[21]
105
105
  detalhe << codigo_carteira # codigo da carteira X[01]
106
- detalhe << '01' # identificacao ocorrencia (remessa) 9[02]
107
- detalhe << pagamento.nosso_numero.to_s.rjust(10, '0') # numero do documento X[10]
106
+ detalhe << pagamento.identificacao_ocorrencia # identificacao ocorrencia 9[02]
107
+ detalhe << pagamento.numero_documento.to_s.rjust(10, '0') # numero do documento X[10]
108
108
  detalhe << pagamento.data_vencimento.strftime('%d%m%y') # data do vencimento 9[06]
109
109
  detalhe << pagamento.formata_valor # valor do documento 9[13]
110
110
  detalhe << cod_banco # codigo banco 9[03]
111
- detalhe << ''.rjust(5, ' ') # agencia cobradora - deixar zero 9[05]
111
+ detalhe << ''.rjust(5, '0') # agencia cobradora - deixar zero 9[05]
112
112
  detalhe << '99' # especie do titulo X[02]
113
113
  detalhe << aceite # aceite (A/N) X[01]
114
114
  detalhe << pagamento.data_emissao.strftime('%d%m%y') # data de emissao 9[06]
115
- detalhe << ''.rjust(2, ' ') # 1a instrucao X[02]
116
- detalhe << ''.rjust(2, ' ') # 2a instrucao X[02]
115
+ detalhe << ''.rjust(2, '0') # 1a instrucao - deixar zero X[02]
116
+ detalhe << ''.rjust(2, '0') # 2a instrucao - deixar zero X[02]
117
117
  detalhe << pagamento.formata_valor_mora # valor mora ao dia 9[13]
118
118
  detalhe << pagamento.formata_data_desconto # data limite para desconto 9[06]
119
119
  detalhe << pagamento.formata_valor_desconto # valor do desconto 9[13]
@@ -0,0 +1,152 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Brcobranca
3
+ module Remessa
4
+ module Cnab400
5
+ class Santander < Brcobranca::Remessa::Cnab400::Base
6
+ # documento do cedente
7
+ attr_accessor :documento_cedente
8
+
9
+ # Código de Transmissão
10
+ # Consultar seu gerente para pegar esse código. Geralmente está no e-mail enviado pelo banco.
11
+ attr_accessor :codigo_transmissao
12
+
13
+ attr_accessor :codigo_carteira
14
+
15
+ validates_presence_of :documento_cedente, :codigo_transmissao, message: 'não pode estar em branco.'
16
+ validates_length_of :documento_cedente, minimum: 11, maximum: 14, message: 'deve ter entre 11 e 14 dígitos.'
17
+ validates_length_of :carteira, maximum: 3, message: 'deve ter no máximo 3 dígitos.'
18
+ validates_length_of :codigo_transmissao, maximum: 20, message: 'deve ter no máximo 20 dígitos.'
19
+
20
+ def initialize(campos = {})
21
+ campos = { aceite: 'N', carteira: '101', codigo_carteira: '1' }.merge!(campos)
22
+ super(campos)
23
+ end
24
+
25
+ def cod_banco
26
+ '033'
27
+ end
28
+
29
+ def nome_banco
30
+ 'SANTANDER'.ljust(15, ' ')
31
+ end
32
+
33
+ # Informacoes do Código de Transmissão
34
+ #
35
+ # @return [String]
36
+ #
37
+ def info_conta
38
+ # CAMPO TAMANHO
39
+ # codigo_transmissao 20
40
+ codigo_transmissao.rjust(20, ' ')
41
+ end
42
+
43
+ # Complemento do header
44
+ #
45
+ # @return [String]
46
+ #
47
+ def complemento
48
+ '58'.rjust(294, ' ')
49
+ end
50
+
51
+ # Detalhe do arquivo
52
+ #
53
+ # @param pagamento [PagamentoCnab400]
54
+ # objeto contendo as informacoes referentes ao boleto (valor, vencimento, cliente)
55
+ # @param sequencial
56
+ # num. sequencial do registro no arquivo
57
+ #
58
+ # @return [String]
59
+ #
60
+ def monta_detalhe(pagamento, sequencial)
61
+ fail Brcobranca::RemessaInvalida.new(pagamento) if pagamento.invalid?
62
+
63
+ detalhe = '1' # identificacao transacao 9[01]
64
+ detalhe << Brcobranca::Util::Empresa.new(documento_cedente).tipo # tipo de identificacao da empresa 9[02]
65
+ detalhe << documento_cedente.to_s.rjust(14, '0') # cpf/cnpj da empresa 9[14]
66
+ detalhe << codigo_transmissao # Código de Transmissão 9[20]
67
+ detalhe << ''.rjust(25, ' ') # identificacao do tit. na empresa X[25]
68
+ detalhe << pagamento.nosso_numero.to_s.rjust(8, '0') # nosso numero 9[8]
69
+ detalhe << pagamento.formata_data_segundo_desconto # data limite para o segundo desconto 9[06]
70
+ detalhe << ''.rjust(1, ' ') # brancos X[1]
71
+ detalhe << pagamento.codigo_multa # Com multa = 4, Sem multa = 0 9[1]
72
+ detalhe << pagamento.percentual_multa.rjust(4, '0') # Percentual multa por atraso % 9[6]
73
+ detalhe << '00' # Unidade de valor moeda corrente = 00 9[2]
74
+ detalhe << '0'.rjust(13, '0') # Valor do título em outra unidade 9[15]
75
+ detalhe << ''.rjust(4, ' ') # brancos X[4]
76
+ detalhe << pagamento.formata_data_multa # Data para cobrança de multa 9[6]
77
+
78
+ # codigo da carteira
79
+ # 1 = ELETRÔNICA COM REGISTRO
80
+ # 3 = CAUCIONADA ELETRÔNICA
81
+ # 4 = COBRANÇA SEM REGISTRO
82
+ # 5 = RÁPIDA COM REGISTRO
83
+ # (BLOQUETE EMITIDO PELO CLIENTE) 6 = CAUCIONADA RAPIDA
84
+ # 7 = DESCONTADA ELETRÔNICA
85
+ detalhe << codigo_carteira # codigo da carteira 9[01]
86
+
87
+ # Código da ocorrência:
88
+ # 01 = ENTRADA DE TÍTULO
89
+ # 02 = BAIXA DE TÍTULO
90
+ # 04 = CONCESSÃO DE ABATIMENTO
91
+ # 05 = CANCELAMENTO ABATIMENTO
92
+ # 06 = PRORROGAÇÃO DE VENCIMENTO
93
+ # 07 = ALT. NÚMERO CONT.CEDENTE
94
+ # 08 = ALTERAÇÃO DO SEU NÚMERO
95
+ # 09 = PROTESTAR
96
+ # 18 = SUSTAR PROTESTO
97
+ detalhe << pagamento.identificacao_ocorrencia # identificacao ocorrencia 9[02]
98
+ detalhe << pagamento.numero_documento.to_s.rjust(10, '0') # numero do documento X[10]
99
+ detalhe << pagamento.data_vencimento.strftime('%d%m%y') # data do vencimento 9[06]
100
+ detalhe << pagamento.formata_valor # valor do documento 9[13]
101
+ detalhe << cod_banco # codigo banco 9[03]
102
+ detalhe << ''.rjust(5, '0') # agencia cobradora - deixar zero 9[05]
103
+
104
+ # Espécie de documento:
105
+ # 01 = DUPLICATA
106
+ # 02 = NOTA PROMISSÓRIA
107
+ # 03 = APÓLICE / NOTA DE SEGURO
108
+ # 05 = RECIBO
109
+ # 06 = DUPLICATA DE SERVIÇO
110
+ # 07 = LETRA DE CAMBIO
111
+ detalhe << pagamento.especie_titulo # Espécie de documento 9[02]
112
+ detalhe << aceite # aceite (A/N) X[01]
113
+ detalhe << pagamento.data_emissao.strftime('%d%m%y') # data de emissao 9[06]
114
+
115
+ # Instrução cobrança
116
+ # 00 = NÃO HÁ INSTRUÇÕES
117
+ # 02 = BAIXAR APÓS QUINZE DIAS DO VENCIMENTO
118
+ # 03 = BAIXAR APÓS 30 DIAS DO VENCIMENTO
119
+ # 04 = NÃO BAIXAR
120
+ # 06 = PROTESTAR (VIDE POSIÇÃO392/393)
121
+ # 07 = NÃO PROTESTAR
122
+ # 08 = NÃO COBRAR JUROS DE MORA
123
+ detalhe << '00' # Instrução para o título 9[02]
124
+ detalhe << '00' # Número de dias válidos para instrução 9[02]
125
+ detalhe << pagamento.formata_valor_mora # valor mora ao dia 9[13]
126
+ detalhe << pagamento.formata_data_desconto # data limite para desconto 9[06]
127
+ detalhe << pagamento.formata_valor_desconto # valor do desconto 9[13]
128
+ detalhe << pagamento.formata_valor_iof # valor do iof 9[13]
129
+ detalhe << pagamento.formata_valor_abatimento # valor do abatimento 9[13]
130
+ detalhe << pagamento.identificacao_sacado # identificacao do pagador 9[02]
131
+ detalhe << pagamento.documento_sacado.to_s.rjust(14, '0') # documento do pagador 9[14]
132
+ detalhe << pagamento.nome_sacado.format_size(40) # nome do pagador X[40]
133
+ detalhe << pagamento.endereco_sacado.format_size(40) # endereco do pagador X[40]
134
+ detalhe << pagamento.bairro_sacado.format_size(12) # bairro do pagador X[12]
135
+ detalhe << pagamento.cep_sacado # cep do pagador 9[08]
136
+ detalhe << pagamento.cidade_sacado.format_size(15) # cidade do pagador X[15]
137
+ detalhe << pagamento.uf_sacado # uf do pagador X[02]
138
+ detalhe << pagamento.nome_avalista.rjust(30, ' ') # Sacador/Mensagens X[40]
139
+ detalhe << ''.rjust(1, ' ') # Brancos X[1]
140
+ detalhe << ''.rjust(1, ' ') # Identificador do Complemento X[1]
141
+ detalhe << ''.rjust(2, ' ') # Complemento 9[2]
142
+ detalhe << ''.rjust(6, ' ') # Brancos X[06]
143
+ # Se identificacao_ocorrencia = 06
144
+ detalhe << '00'.rjust(2, ' ') # Número de dias para protesto 9[02]
145
+ detalhe << ''.rjust(1, ' ') # Brancos X[1]
146
+ detalhe << sequencial.to_s.rjust(6, '0') # numero do registro no arquivo 9[06]
147
+ detalhe.upcase
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -27,6 +27,8 @@ module Brcobranca
27
27
  attr_accessor :cidade_sacado
28
28
  # <b>REQUERIDO</b>: UF do sacado (cliente)
29
29
  attr_accessor :uf_sacado
30
+ # <b>REQUERIDO</b>: Código da ocorrência
31
+ attr_accessor :identificacao_ocorrencia
30
32
  # <b>OPCIONAL</b>: nome do avalista
31
33
  attr_accessor :nome_avalista
32
34
  # <b>OPCIONAL</b>: documento do avalista
@@ -57,12 +59,22 @@ module Brcobranca
57
59
  attr_accessor :data_segundo_desconto
58
60
  # <b>OPCIONAL</b>: valor a ser concedido de desconto
59
61
  attr_accessor :valor_segundo_desconto
62
+ # <b>OPCIONAL</b>: espécie do título
63
+ attr_accessor :especie_titulo
64
+ # <b>OPCIONAL</b>: código da multa
65
+ attr_accessor :codigo_multa
66
+ # <b>OPCIONAL</b>: Percentual multa por atraso %
67
+ attr_accessor :percentual_multa
68
+ # <b>OPCIONAL</b>: Data para cobrança de multa
69
+ attr_accessor :data_multa
60
70
 
61
71
  validates_presence_of :nosso_numero, :data_vencimento, :valor,
62
- :documento_sacado, :nome_sacado, :endereco_sacado,
63
- :cep_sacado, :cidade_sacado, :uf_sacado, message: 'não pode estar em branco.'
72
+ :documento_sacado, :nome_sacado, :endereco_sacado,
73
+ :cep_sacado, :cidade_sacado, :uf_sacado, message: 'não pode estar em branco.'
64
74
  validates_length_of :cep_sacado, is: 8, message: 'deve ter 8 dígitos.'
65
75
  validates_length_of :cod_desconto, is: 1, message: 'deve ter 1 dígito.'
76
+ validates_length_of :especie_titulo, is: 2, message: 'deve ter 2 dígitos.', allow_blank: true
77
+ validates_length_of :identificacao_ocorrencia, is: 2, message: 'deve ter 2 dígitos.'
66
78
 
67
79
  # Nova instancia da classe Pagamento
68
80
  #
@@ -77,7 +89,11 @@ module Brcobranca
77
89
  valor_iof: 0.0,
78
90
  valor_abatimento: 0.0,
79
91
  nome_avalista: '',
80
- cod_desconto: '0'
92
+ cod_desconto: '0',
93
+ especie_titulo: '01',
94
+ identificacao_ocorrencia: '01',
95
+ codigo_multa: '0',
96
+ percentual_multa: '0'
81
97
  }
82
98
 
83
99
  campos = padrao.merge!(campos)
@@ -116,6 +132,20 @@ module Brcobranca
116
132
  end
117
133
  end
118
134
 
135
+ # Formata a data de cobrança da multa
136
+ #
137
+ # @return [String]
138
+ #
139
+ def formata_data_multa(formato = '%d%m%y')
140
+ data_multa.strftime(formato)
141
+ rescue
142
+ if formato == '%d%m%y'
143
+ '000000'
144
+ else
145
+ '00000000'
146
+ end
147
+ end
148
+
119
149
  # Formata o campo valor
120
150
  # referentes as casas decimais
121
151
  # exe. R$199,90 => 0000000019990
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  module Brcobranca
4
- VERSION = '5.0.1'
4
+ VERSION = '5.0.2'
5
5
  end
@@ -63,7 +63,7 @@ RSpec.describe Brcobranca::Boleto::Sicoob do #:nodoc:[all]
63
63
  expect(boleto_novo.conta_corrente).to eql("0417270")
64
64
  expect(boleto_novo.agencia).to eql("3007")
65
65
  expect(boleto_novo.convenio).to eql("0318957")
66
- expect(boleto_novo.numero_documento).to eql("000240")
66
+ expect(boleto_novo.numero_documento).to eql("0000240")
67
67
  expect(boleto_novo.carteira).to eql("1")
68
68
  expect(boleto_novo.codigo_servico).to be_falsey
69
69
  end
@@ -174,6 +174,20 @@ RSpec.describe Brcobranca::Calculo do
174
174
  it { expect { modulo_11_de_2_ate_9 '2582fd81' }.to raise_error(ArgumentError) }
175
175
  end
176
176
 
177
+ # Ex: Sicoob
178
+ describe 'Módulo 11 com multiplicadores 3, 7, 9, 1, trocando 11 e 10 por 0' do
179
+ def modulo_11_com_3_7_9_1_map_10_e_10_por_0(numero)
180
+ numero.modulo11(
181
+ multiplicador: [3, 7, 9, 1],
182
+ mapeamento: { 10 => 0, 11 => 0 }
183
+ ) { |t| 11 - (t % 11) }
184
+ end
185
+
186
+ it { expect(modulo_11_com_3_7_9_1_map_10_e_10_por_0 "000100000000190000045").to eql(4) }
187
+ it { expect(modulo_11_com_3_7_9_1_map_10_e_10_por_0 "442300000520270100183").to eql(4) }
188
+ it { expect(modulo_11_com_3_7_9_1_map_10_e_10_por_0 "442300000520270100184").to eql(1) }
189
+ end
190
+
177
191
  # Ex: Bradesco
178
192
  describe 'Módulo 11 de 2 até 7 trocando 10 por P e 11 por 0' do
179
193
  def modulo_11_de_2_ate_7_map_10_P_e_11_0(numero)
@@ -70,18 +70,18 @@ RSpec.describe Brcobranca::Remessa::Cnab240::BancoBrasil do
70
70
  end
71
71
 
72
72
  context '@agencia' do
73
- it 'deve ser invalido se a agencia tiver mais de 4 digitos' do
74
- banco_brasil.agencia = '12345'
73
+ it 'deve ser invalido se a agencia tiver mais de 5 digitos' do
74
+ banco_brasil.agencia = '123456'
75
75
  expect(banco_brasil.invalid?).to be true
76
- expect(banco_brasil.errors.full_messages).to include('Agencia deve ter 4 dígitos.')
76
+ expect(banco_brasil.errors.full_messages).to include('Agencia deve ter 5 dígitos.')
77
77
  end
78
78
  end
79
79
 
80
80
  context '@conta_corrente' do
81
- it 'deve ser invalido se a conta corrente tiver mais de 5 digitos' do
82
- banco_brasil.conta_corrente = '123456'
81
+ it 'deve ser invalido se a conta corrente tiver mais de 12 digitos' do
82
+ banco_brasil.conta_corrente = '1234567890123'
83
83
  expect(banco_brasil.invalid?).to be true
84
- expect(banco_brasil.errors.full_messages).to include('Conta corrente deve ter 5 dígitos.')
84
+ expect(banco_brasil.errors.full_messages).to include('Conta corrente deve ter 12 dígitos.')
85
85
  end
86
86
  end
87
87
  end
@@ -64,10 +64,10 @@ RSpec.describe Brcobranca::Remessa::Cnab240::Sicoob do
64
64
  end
65
65
 
66
66
  context '@conta_corrente' do
67
- it 'deve ser invalido se a conta corrente tiver mais de 5 digitos' do
68
- sicoob.conta_corrente = '123456'
67
+ it 'deve ser invalido se a conta corrente tiver mais de 8 digitos' do
68
+ sicoob.conta_corrente = '123456789'
69
69
  expect(sicoob.invalid?).to be true
70
- expect(sicoob.errors.full_messages).to include('Conta corrente deve ter 5 dígitos.')
70
+ expect(sicoob.errors.full_messages).to include('Conta corrente deve ter 8 dígitos.')
71
71
  end
72
72
  end
73
73
  end
@@ -157,6 +157,9 @@ RSpec.describe Brcobranca::Remessa::Cnab400::Itau do
157
157
  expect(detalhe[62..69]).to eq '00000123' # nosso numero
158
158
  expect(detalhe[120..125]).to eq Date.today.strftime('%d%m%y') # data de vencimento
159
159
  expect(detalhe[126..138]).to eq '0000000019990' # valor do titulo
160
+ expect(detalhe[142..146]).to eq '00000' # agência cobradora
161
+ expect(detalhe[156..157]).to eq '00' # instrução 1
162
+ expect(detalhe[158..159]).to eq '00' # instrução 2
160
163
  expect(detalhe[220..233]).to eq '00012345678901' # documento do pagador
161
164
  expect(detalhe[234..263]).to eq 'NOME'.ljust(30, ' ') # nome do pagador
162
165
  end
@@ -0,0 +1,116 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Brcobranca::Remessa::Cnab400::Santander do
5
+ let(:pagamento) do
6
+ Brcobranca::Remessa::Pagamento.new(valor: 199.9,
7
+ data_vencimento: Date.today,
8
+ nosso_numero: 123,
9
+ documento_sacado: '12345678901',
10
+ nome_sacado: 'nome',
11
+ endereco_sacado: 'endereco',
12
+ bairro_sacado: 'bairro',
13
+ cep_sacado: '12345678',
14
+ cidade_sacado: 'cidade',
15
+ uf_sacado: 'SP')
16
+ end
17
+ let(:params) do
18
+ {
19
+ codigo_transmissao: '17777751042700080112',
20
+ empresa_mae: 'asd',
21
+ documento_cedente: '12345678910',
22
+ pagamentos: [pagamento]
23
+ }
24
+ end
25
+ let(:santander_cnab400) { subject.class.new(params) }
26
+
27
+ context 'validacoes dos campos' do
28
+ context '@carteira' do
29
+ it 'deve ser invalido se nao possuir uma carteira' do
30
+ object = subject.class.new(params.merge!(carteira: nil))
31
+ expect(object.invalid?).to be true
32
+ expect(object.errors.full_messages).to include('Carteira não pode estar em branco.')
33
+ end
34
+
35
+ it 'deve ser invalido se a carteira tiver mais de 3 digitos' do
36
+ santander_cnab400.carteira = '12345'
37
+ expect(santander_cnab400.invalid?).to be true
38
+ expect(santander_cnab400.errors.full_messages).to include('Carteira deve ter no máximo 3 dígitos.')
39
+ end
40
+ end
41
+
42
+ context '@documento_cedente' do
43
+ it 'deve ser invalido se nao possuir o documento cedente' do
44
+ object = subject.class.new(params.merge!(documento_cedente: nil))
45
+ expect(object.invalid?).to be true
46
+ expect(object.errors.full_messages).to include('Documento cedente não pode estar em branco.')
47
+ end
48
+
49
+ it 'deve ser invalido se o documento do cedente nao tiver entre 11 e 14 digitos' do
50
+ santander_cnab400.documento_cedente = '123'
51
+ expect(santander_cnab400.invalid?).to be true
52
+ expect(santander_cnab400.errors.full_messages).to include('Documento cedente deve ter entre 11 e 14 dígitos.')
53
+ end
54
+ end
55
+
56
+ context '@codigo_transmissao' do
57
+ it 'deve ser invalido se nao possuir o codigo_transmissao' do
58
+ object = subject.class.new(params.merge!(codigo_transmissao: nil))
59
+ expect(object.invalid?).to be true
60
+ expect(object.errors.full_messages).to include('Codigo transmissao não pode estar em branco.')
61
+ end
62
+
63
+ it 'deve ser invalido se o deve ter no máximo 20 dígitos.' do
64
+ santander_cnab400.codigo_transmissao = '123456789012345678901'
65
+ expect(santander_cnab400.invalid?).to be true
66
+ expect(santander_cnab400.errors.full_messages).to include('Codigo transmissao deve ter no máximo 20 dígitos.')
67
+ end
68
+ end
69
+ end
70
+
71
+ context 'formatacoes dos valores' do
72
+ it 'cod_banco deve ser 341' do
73
+ expect(santander_cnab400.cod_banco).to eq '033'
74
+ end
75
+
76
+ it 'nome_banco deve ser SANTANDER' do
77
+ nome_banco = santander_cnab400.nome_banco
78
+ expect(nome_banco.strip).to eq 'SANTANDER'
79
+ end
80
+
81
+ it 'complemento deve retornar 294 caracteres' do
82
+ expect(santander_cnab400.complemento.size).to eq 294
83
+ end
84
+
85
+ it 'info_conta deve retornar com 20 posicoes as informacoes da conta' do
86
+ info_conta = santander_cnab400.info_conta
87
+ expect(info_conta.size).to eq 20
88
+ expect(info_conta[0..19]).to eq '17777751042700080112' # codigo_transmissao
89
+ end
90
+ end
91
+
92
+ context 'monta remessa' do
93
+ it_behaves_like 'cnab400'
94
+
95
+ context 'header' do
96
+ it 'informacoes devem estar posicionadas corretamente no header' do
97
+ header = santander_cnab400.monta_header
98
+ expect(header[1]).to eq '1' # tipo operacao (1 = remessa)
99
+ expect(header[2..8]).to eq 'REMESSA' # literal da operacao
100
+ expect(header[26..45]).to eq santander_cnab400.info_conta # informacoes da conta
101
+ expect(header[76..78]).to eq '033' # codigo do banco
102
+ end
103
+ end
104
+
105
+ context 'detalhe' do
106
+ it 'informacoes devem estar posicionadas corretamente no detalhe' do
107
+ detalhe = santander_cnab400.monta_detalhe pagamento, 1
108
+ expect(detalhe[62..69]).to eq '00000123' # nosso numero
109
+ expect(detalhe[120..125]).to eq Date.today.strftime('%d%m%y') # data de vencimento
110
+ expect(detalhe[126..138]).to eq '0000000019990' # valor do titulo
111
+ expect(detalhe[220..233]).to eq '00012345678901' # documento do pagador
112
+ expect(detalhe[234..263]).to eq 'NOME'.ljust(30, ' ') # nome do pagador
113
+ end
114
+ end
115
+ end
116
+ end
@@ -156,19 +156,15 @@ shared_examples_for 'cnab240' do
156
156
  end
157
157
 
158
158
  context 'monta lote' do
159
- it 'deve falhar se o pagamento passado nao for valido' do
160
- expect { objeto.monta_lote(Brcobranca::Remessa::Pagamento.new, 1) }.to raise_error(Brcobranca::RemessaInvalida)
161
- end
162
-
163
159
  it 'retorno de lote deve ser uma colecao com os registros' do
164
- lote = objeto.monta_lote pagamento, 1
160
+ lote = objeto.monta_lote(1)
165
161
 
166
162
  expect(lote.is_a?(Array)).to be true
167
163
  expect(lote.count).to be 4 # header, segmento p, segmento q e trailer
168
164
  end
169
165
 
170
166
  it 'contador de registros deve acrescer 1 a cada registro' do
171
- lote = objeto.monta_lote pagamento, 1
167
+ lote = objeto.monta_lote(1)
172
168
 
173
169
  expect(lote[1][8..12]).to eq '00001' # segmento P
174
170
  expect(lote[2][8..12]).to eq '00002' # segmento Q
@@ -192,17 +188,5 @@ shared_examples_for 'cnab240' do
192
188
  expect(remessa[963]).to eq "\n"
193
189
  expect(remessa[1204]).to eq "\n"
194
190
  end
195
-
196
- # TODO no momento só existe um lote e todos os pagamentos são adicionados a ele
197
- it 'pode ser adicionado varios lotes' do
198
- objeto.pagamentos << pagamento
199
- remessa = objeto.gera_arquivo
200
- lote1 = remessa[241..1203]
201
- lote2 = remessa[1205..2167]
202
-
203
- # 10 registros (2400) + 9 quebras de linha (18)
204
- expect(remessa.size).to eq 2409
205
- expect(lote1).to eq objeto.monta_lote(pagamento, 1).join("\n")
206
- end
207
191
  end
208
192
  end
@@ -30,6 +30,13 @@ shared_examples_for 'cnab400' do
30
30
  documento_cedente: '12345678910',
31
31
  pagamentos: [pagamento]
32
32
  }
33
+ elsif subject.class == Brcobranca::Remessa::Cnab400::Santander
34
+ {
35
+ codigo_transmissao: '17777751042700080112',
36
+ empresa_mae: 'ASD',
37
+ documento_cedente: '12345678910',
38
+ pagamentos: [pagamento]
39
+ }
33
40
  else
34
41
  { carteira: '123',
35
42
  agencia: '1234',
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brcobranca
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 5.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kivanio Barbosa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-21 00:00:00.000000000 Z
11
+ date: 2015-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rghost
@@ -138,6 +138,7 @@ files:
138
138
  - lib/brcobranca/remessa/cnab400/bradesco.rb
139
139
  - lib/brcobranca/remessa/cnab400/citibank.rb
140
140
  - lib/brcobranca/remessa/cnab400/itau.rb
141
+ - lib/brcobranca/remessa/cnab400/santander.rb
141
142
  - lib/brcobranca/remessa/pagamento.rb
142
143
  - lib/brcobranca/retorno/base.rb
143
144
  - lib/brcobranca/retorno/cnab400/base.rb
@@ -174,6 +175,7 @@ files:
174
175
  - spec/brcobranca/remessa/cnab400/bradesco_spec.rb
175
176
  - spec/brcobranca/remessa/cnab400/citibank_spec.rb
176
177
  - spec/brcobranca/remessa/cnab400/itau_spec.rb
178
+ - spec/brcobranca/remessa/cnab400/santander_spec.rb
177
179
  - spec/brcobranca/remessa/pagamento_spec.rb
178
180
  - spec/brcobranca/retorno/cnab400/base_spec.rb
179
181
  - spec/brcobranca/retorno/cnab400/bradesco_spec.rb
@@ -211,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
213
  requirements:
212
214
  - GhostScript > 9.0, para gear PDF e código de Barras
213
215
  rubyforge_project:
214
- rubygems_version: 2.4.8
216
+ rubygems_version: 2.4.5.1
215
217
  signing_key:
216
218
  specification_version: 4
217
219
  summary: Gem que permite trabalhar com bloquetos de cobranca para bancos brasileiros.
@@ -242,6 +244,7 @@ test_files:
242
244
  - spec/brcobranca/remessa/cnab400/bradesco_spec.rb
243
245
  - spec/brcobranca/remessa/cnab400/citibank_spec.rb
244
246
  - spec/brcobranca/remessa/cnab400/itau_spec.rb
247
+ - spec/brcobranca/remessa/cnab400/santander_spec.rb
245
248
  - spec/brcobranca/remessa/pagamento_spec.rb
246
249
  - spec/brcobranca/retorno/cnab400/base_spec.rb
247
250
  - spec/brcobranca/retorno/cnab400/bradesco_spec.rb