From b66929e3d25edeaaca03f92f7b9911ab9fac33c8 Mon Sep 17 00:00:00 2001 From: Henrique Date: Fri, 5 Jan 2024 13:16:31 -0300 Subject: [PATCH] Adiciona Santander CNABb240 Remessa --- README.md | 37 +- lib/brcobranca.rb | 1 + lib/brcobranca/remessa/cnab240/santander.rb | 222 ++++++++++++ .../remessa/cnab240/santander_spec.rb | 318 ++++++++++++++++++ .../remessa/remessa-santander-cnab240.rem | 7 + 5 files changed, 567 insertions(+), 18 deletions(-) create mode 100644 lib/brcobranca/remessa/cnab240/santander.rb create mode 100644 spec/brcobranca/remessa/cnab240/santander_spec.rb create mode 100644 spec/fixtures/remessa/remessa-santander-cnab240.rem diff --git a/README.md b/README.md index 214657e6..d87fe231 100644 --- a/README.md +++ b/README.md @@ -42,24 +42,24 @@ Criado pelo pessoal da [Akretion](http://www.akretion.com) muito TOP \o/ ### Retornos e Remessas -| Banco | Retorno | Remessa | -| ----------------- | -------------- | --------------------- | -| Banco do Brasil | 400(ou CBR643) | 400 (ou CBR641) e 240 | -| Banco do Nordeste | 400 | 400 | -| Banco de Brasília | Não | 400 | -| Banestes | Sim | Não | -| Banrisul | 400 | 400 | -| Bradesco | 400 | 400 | -| Caixa | 240 | 240 | -| Citibank | Não | 400 | -| HSBC | Não | Não | -| Itaú | 400 | 400 | -| Santander | 240 | 400 | -| Sicoob | 240 | 400 e 240 | -| Sicredi | 240 | 240 | -| UNICRED | 400 | 400 e 240 | -| AILOS | 240 | 240 | -| CREDISIS | 400 | 400 | +| Banco | Retorno | Remessa | +| ----------------- | --------------- | --------------------- | +| Banco do Brasil | 400 (ou CBR643) | 400 (ou CBR641) e 240 | +| Banco do Nordeste | 400 | 400 | +| Banco de Brasília | 400 | 400 | +| Banestes | Não | Não | +| Banrisul | 400 | 400 | +| Bradesco | 400 | 400 | +| Caixa | 240 | 240 | +| Citibank | Não | 400 | +| HSBC | Não | Não | +| Itaú | 400 | 400 | +| Santander | 400 e 240 | 400 e 240 | +| Sicoob | 240 | 400 e 240 | +| Sicredi | 240 | 240 | +| UNICRED | 400 | 400 e 240 | +| AILOS | 240 | 240 | +| CREDISIS | 400 | 400 | - Banco do Brasil (CNAB240) [Isabella](https://github.com/isabellaSantos) da [Zaez](http://www.zaez.net) - Caixa Economica Federal (CNAB240) [Isabella](https://github.com/isabellaSantos) da [Zaez](http://www.zaez.net) @@ -67,6 +67,7 @@ Criado pelo pessoal da [Akretion](http://www.akretion.com) muito TOP \o/ - Itaú (CNAB400) [Isabella](https://github.com/isabellaSantos) da [Zaez](http://www.zaez.net) - Citibank (CNAB400) - Santander (CNAB400) +- Santander (CNAB240) ### Documentação diff --git a/lib/brcobranca.rb b/lib/brcobranca.rb index 07632708..dec357d9 100755 --- a/lib/brcobranca.rb +++ b/lib/brcobranca.rb @@ -181,6 +181,7 @@ module Cnab240 autoload :BaseCorrespondente, 'brcobranca/remessa/cnab240/base_correspondente' autoload :Caixa, 'brcobranca/remessa/cnab240/caixa' autoload :BancoBrasil, 'brcobranca/remessa/cnab240/banco_brasil' + autoload :Santander, 'brcobranca/remessa/cnab240/santander' autoload :Sicoob, 'brcobranca/remessa/cnab240/sicoob' autoload :SicoobBancoBrasil, 'brcobranca/remessa/cnab240/sicoob_banco_brasil' autoload :Sicredi, 'brcobranca/remessa/cnab240/sicredi' diff --git a/lib/brcobranca/remessa/cnab240/santander.rb b/lib/brcobranca/remessa/cnab240/santander.rb new file mode 100644 index 00000000..251040be --- /dev/null +++ b/lib/brcobranca/remessa/cnab240/santander.rb @@ -0,0 +1,222 @@ +# frozen_string_literal: true + +module Brcobranca + module Remessa + module Cnab240 + class Santander < Brcobranca::Remessa::Cnab240::Base + + # Código de Transmissão + attr_accessor :codigo_transmissao + # Dígito da Agência + attr_accessor :digito_agencia + + validates_presence_of :codigo_transmissao, :digito_agencia, :digito_conta, message: 'não pode estar em branco.' + + validates_length_of :codigo_transmissao, maximum: 15, message: 'deve ter no máximo 15 dígitos.' + validates_length_of :agencia, maximum: 4, message: 'deve ter 4 dígitos.' + validates_length_of :digito_agencia, maximum: 1, message: 'deve ter 1 dígito.' + validates_length_of :conta_corrente, maximum: 9, message: 'deve ter 9 dígitos.' + validates_length_of :digito_conta, maximum: 1, message: 'deve ter 1 dígito.' + + def initialize(campos = {}) + campos = { emissao_boleto: ' ', distribuicao_boleto: ' ', + especie_titulo: '02', tipo_documento: '2' }.merge!(campos) + super(campos) + end + + def codigo_transmissao=(valor) + @codigo_transmissao = valor.to_s.strip.rjust(15, '0') if valor + end + + def complemento_header + ''.rjust(29, ' ') + end + + def complemento_trailer + ''.rjust(217, ' ') + end + + def complemento_p(pagamento) + complemento_p = '' + complemento_p += conta_corrente.rjust(9, '0') + complemento_p << digito_conta.to_s + complemento_p << conta_corrente.rjust(9, '0') + complemento_p << digito_conta.to_s + complemento_p << ' ' + complemento_p << identificador_titulo(pagamento.nosso_numero) + complemento_p + end + + def complemento_r + ''.rjust(61, ' ') + end + + def versao_layout_arquivo + '040' + end + + def versao_layout_lote + '030' + end + + def convenio_lote + identificacao_conta = '' + identificacao_conta += ''.rjust(20, ' ') + identificacao_conta << codigo_transmissao + identificacao_conta << ''.rjust(5, ' ') + identificacao_conta + end + + def nome_banco + 'BANCO SANTANDER'.ljust(30, ' ') + end + + def cod_banco + '033' + end + + def info_conta + '' + end + + def codigo_convenio + identificacao_conta = '' + identificacao_conta += codigo_transmissao + identificacao_conta << ''.rjust(25, ' ') + identificacao_conta + end + + def identificador_titulo(nosso_numero) + nosso_numero_dv = nosso_numero.modulo11( + multiplicador: (2..9).to_a, + mapeamento: { 10 => 0, 11 => 0 } + ) { |total| 11 - (total % 11) } + + "#{nosso_numero}#{nosso_numero_dv}".rjust(13, '0') + end + + def formata_documento_ou_numero(pagamento, tamanho = 25, caracter = ' ') + doc = pagamento.documento_ou_numero.to_s.gsub(/[^0-9A-Za-z ]/, '') + doc.ljust(tamanho, caracter)[0...tamanho] + end + + def densidade_gravacao + ''.rjust(5, ' ') + end + + def uso_exclusivo_banco + ''.rjust(20, ' ') + end + + def uso_exclusivo_empresa + ''.rjust(20, ' ') + end + + def hora_geracao + ''.rjust(6, ' ') + end + + def dv_agencia_cobradora + ''.rjust(1, ' ') + end + + def monta_header_arquivo + header_arquivo = '' # CAMPO TAMANHO + header_arquivo += cod_banco # codigo do banco 3 + header_arquivo << '0000' # lote do servico 4 + header_arquivo << '0' # tipo de registro 1 + header_arquivo << ''.rjust(8, ' ') # uso exclusivo FEBRABAN 9 + header_arquivo << Brcobranca::Util::Empresa.new(documento_cedente, false).tipo # tipo inscricao 1 + header_arquivo << documento_cedente.to_s.rjust(15, '0') # numero de inscricao 15 + header_arquivo << codigo_convenio # codigo do convenio no banco 20 + header_arquivo << info_conta # informacoes da conta 20 + header_arquivo << empresa_mae.format_size(30) # nome da empresa 30 + header_arquivo << nome_banco.format_size(30) # nome do banco 30 + header_arquivo << ''.rjust(10, ' ') # uso exclusivo FEBRABAN 10 + header_arquivo << '1' # codigo remessa 1 + header_arquivo << data_geracao # data geracao 8 + header_arquivo << hora_geracao # hora geracao 6 + header_arquivo << sequencial_remessa.to_s.rjust(6, '0') # numero seq. arquivo 6 + header_arquivo << versao_layout_arquivo # num. versao arquivo 3 + header_arquivo << densidade_gravacao # densidade gravacao 5 + header_arquivo << uso_exclusivo_banco # uso exclusivo 20 + header_arquivo << uso_exclusivo_empresa # uso exclusivo 20 + header_arquivo << complemento_header # complemento do arquivo 29 + header_arquivo + end + + def monta_segmento_p(pagamento, nro_lote, sequencial) + segmento_p = '' + # # DESCRICAO TAMANHO + segmento_p += cod_banco # codigo banco 3 + segmento_p << nro_lote.to_s.rjust(4, '0') # lote de servico 4 + segmento_p << '3' # tipo de registro 1 + segmento_p << sequencial.to_s.rjust(5, '0') # num. sequencial do registro no lote 5 + segmento_p << 'P' # cod. segmento 1 + segmento_p << ' ' # uso exclusivo 1 + segmento_p << pagamento.identificacao_ocorrencia # cod. movimento remessa 2 + segmento_p << agencia.to_s.rjust(4, '0') # agencia 4 + segmento_p << digito_agencia.to_s # dv agencia 1 + segmento_p << complemento_p(pagamento) # informacoes da conta 34 + segmento_p << codigo_carteira # codigo da carteira 1 + segmento_p << forma_cadastramento # forma de cadastro do titulo 1 + segmento_p << tipo_documento # tipo de documento 1 + segmento_p << emissao_boleto # identificaco emissao 1 + segmento_p << distribuicao_boleto # indentificacao entrega 1 + segmento_p << formata_documento_ou_numero(pagamento, 15) # uso exclusivo 4 + segmento_p << pagamento.data_vencimento.strftime('%d%m%Y') # data de venc. 8 + segmento_p << pagamento.formata_valor(15) # valor documento 15 + segmento_p << ''.rjust(5, '0') # agencia cobradora 5 + segmento_p << dv_agencia_cobradora # dv agencia cobradora 1 + segmento_p << especie_titulo # especie do titulo 2 + segmento_p << aceite # aceite 1 + segmento_p << pagamento.data_emissao.strftime('%d%m%Y') # data de emissao titulo 8 + segmento_p << pagamento.tipo_mora # cod. do mora 1 + segmento_p << data_mora(pagamento) # data mora 8 + segmento_p << pagamento.formata_valor_mora(15) # valor mora 15 + segmento_p << codigo_desconto(pagamento) # cod. do desconto 1 + segmento_p << pagamento.formata_data_desconto('%d%m%Y') # data desconto 8 + segmento_p << pagamento.formata_valor_desconto(15) # valor desconto 15 + segmento_p << pagamento.formata_valor_iof(15) # valor IOF 15 + segmento_p << pagamento.formata_valor_abatimento(15) # valor abatimento 15 + segmento_p << formata_documento_ou_numero(pagamento) # identificacao titulo empresa 25 + segmento_p << pagamento.codigo_protesto # cod. para protesto 1 + segmento_p << pagamento.dias_protesto.to_s.rjust(2, '0') # dias para protesto 2 + segmento_p << '3' # cod. para baixa 1 + segmento_p << '0' # zero fixo 1 + segmento_p << '00' # dias para baixa 2 + segmento_p << '00' # cod. da moeda 2 + segmento_p << ''.rjust(11, ' ') # uso exclusivo 11 + segmento_p + end + + def monta_segmento_q(pagamento, nro_lote, sequencial) + segmento_q = '' # CAMPO TAMANHO + segmento_q += cod_banco # codigo banco 3 + segmento_q << nro_lote.to_s.rjust(4, '0') # lote de servico 4 + segmento_q << '3' # tipo de registro 1 + segmento_q << sequencial.to_s.rjust(5, '0') # num. sequencial do registro no lote 5 + segmento_q << 'Q' # cod. segmento 1 + segmento_q << ' ' # uso exclusivo 1 + segmento_q << pagamento.identificacao_ocorrencia # cod. movimento remessa 2 + segmento_q << pagamento.identificacao_sacado(false) # tipo insc. sacado 1 + segmento_q << pagamento.documento_sacado.to_s.rjust(15, '0') # documento sacado 14 + segmento_q << pagamento.nome_sacado.format_size(40) # nome cliente 40 + segmento_q << pagamento.endereco_sacado.format_size(40) # endereco cliente 40 + segmento_q << pagamento.bairro_sacado.format_size(15) # bairro 15 + segmento_q << pagamento.cep_sacado[0..4] # cep 5 + segmento_q << pagamento.cep_sacado[5..7] # sufixo cep 3 + segmento_q << pagamento.cidade_sacado.format_size(15) # cidade 15 + segmento_q << pagamento.uf_sacado # uf 2 + segmento_q << pagamento.identificacao_avalista(false) # identificacao do sacador 1 + segmento_q << pagamento.documento_avalista.to_s.rjust(15, '0') # documento sacador 15 + segmento_q << pagamento.nome_avalista.format_size(40) # nome avalista 40 + segmento_q << ''.rjust(12, '0') # Reservado (uso Branco) 12 + segmento_q << ''.rjust(19, ' ') # Reservado (uso Branco) 19 + segmento_q + end + + end + end + end +end diff --git a/spec/brcobranca/remessa/cnab240/santander_spec.rb b/spec/brcobranca/remessa/cnab240/santander_spec.rb new file mode 100644 index 00000000..a232df40 --- /dev/null +++ b/spec/brcobranca/remessa/cnab240/santander_spec.rb @@ -0,0 +1,318 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Brcobranca::Remessa::Cnab240::Santander do + let(:pagamento) do + Brcobranca::Remessa::Pagamento.new(valor: 199.9, + data_vencimento: Date.current, + nosso_numero: 1234567, + documento: 9999, + documento_sacado: '12345678901', + nome_sacado: 'PABLO DIEGO JOSÉ FRANCISCO,!^.?\/@ DE PAULA JUAN NEPOMUCENO MARÍA DE LOS REMEDIOS CIPRIANO DE LA SANTÍSSIMA TRINIDAD RUIZ Y PICASSO', + endereco_sacado: 'RUA RIO GRANDE DO SUL,!^.?\/@ São paulo Minas caçapa da silva junior', + bairro_sacado: 'São josé dos quatro apostolos magros', + cep_sacado: '12345678', + cidade_sacado: 'Santa rita de cássia maria da silva', + uf_sacado: 'SP', + numero: '123' + ) + end + let(:params) do + { empresa_mae: 'SOCIEDADE BRASILEIRA DE ZOOLOGIA LTDA', + documento_cedente: '28254225000193', + codigo_transmissao: '000100001234567', + agencia: '0001', + digito_agencia: '3', + conta_corrente: '013001234', + digito_conta: '1', + sequencial_remessa: '1', + pagamentos: [pagamento] } + end + let(:santander) { subject.class.new(params) } + + context 'validacoes' do + context '@codigo_transmissao' do + it 'deve ser invalido se nao possuir o codigo_transmissao' do + object = subject.class.new(params.merge!(codigo_transmissao: nil)) + expect(object.invalid?).to be true + expect(object.errors.full_messages).to include('Codigo transmissao não pode estar em branco.') + end + + it 'deve ser invalido se o codigo_transmissao tiver mais de 15 digitos' do + santander.codigo_transmissao = '01234567890123456789' + expect(santander.invalid?).to be true + expect(santander.errors.full_messages).to include('Codigo transmissao deve ter no máximo 15 dígitos.') + end + end + + context '@agencia' do + it 'deve ser invalido se a agencia tiver mais de 4 digitos' do + santander.agencia = '12345' + expect(santander.invalid?).to be true + expect(santander.errors.full_messages).to include('Agencia deve ter 4 dígitos.') + end + + it 'deve ser invalido se o digito_agencia tiver mais de 1 digito' do + santander.digito_agencia = '12' + expect(santander.invalid?).to be true + expect(santander.errors.full_messages).to include('Digito agencia deve ter 1 dígito.') + end + end + + context '@conta_corrente' do + it 'deve ser invalido se a conta_corrente tiver mais de 9 digitos' do + santander.conta_corrente = '1234567890' + expect(santander.invalid?).to be true + expect(santander.errors.full_messages).to include('Conta corrente deve ter 9 dígitos.') + end + + it 'deve ser invalido se o digito_conta tiver mais de 1 digito' do + santander.digito_conta = '12' + expect(santander.invalid?).to be true + expect(santander.errors.full_messages).to include('Digito conta deve ter 1 dígito.') + end + end + end + + context 'formatacoes' do + it 'codigo do banco deve ser 033' do + expect(santander.cod_banco).to eq '033' + end + + it 'nome do banco deve BANCO SANTANDER com 30 posicoes' do + nome_banco = santander.nome_banco + expect(nome_banco.size).to eq 30 + expect(nome_banco[0..14]).to eq 'BANCO SANTANDER' + end + + it 'versao do layout do arquivo deve ser 040' do + expect(santander.versao_layout_arquivo).to eq '040' + end + + it 'versao do layout do lote deve ser 030' do + expect(santander.versao_layout_lote).to eq '030' + end + + it 'convenio lote deve retornar as informacoes nas posicoes corretas' do + convenio_lote = santander.convenio_lote + expect(convenio_lote[0..19]).to eq ''.rjust(20, ' ') + expect(convenio_lote[20..34]).to eq '000100001234567' + expect(convenio_lote[35..40]).to eq ''.rjust(5, ' ') + end + + it 'codigo convenio deve retornar as informacoes nas posicoes corretas' do + codigo_convenio = santander.codigo_convenio + expect(codigo_convenio[0..14]).to eq '000100001234567' + expect(codigo_convenio[15..40]).to eq ''.rjust(25, ' ') + end + + it 'info conta deve retornar branco' do + expect(santander.info_conta).to eq '' + end + + it 'complemento header deve retornar espacos em branco' do + expect(santander.complemento_header).to eq ''.rjust(29, ' ') + end + + it 'complemento trailer deve retornar espacos em branco' do + expect(santander.complemento_trailer).to eq ''.rjust(217, ' ') + end + + it 'identificador do titulo deve ter as informacoes nas posicoes corretas' do + identificador = santander.identificador_titulo(1234567) + expect(identificador).to eq '0000012345679' + end + end + + context 'geracao remessa' do + before { Timecop.freeze(Time.local(2015, 7, 14, 16, 15, 15)) } + + after { Timecop.return } + + context 'header arquivo' do + it 'header arquivo deve ter 240 posicoes' do + expect(santander.monta_header_arquivo.size).to eq 240 + end + + it 'header arquivo deve ter as informacoes nas posicoes corretas' do + header = santander.monta_header_arquivo + expect(header[0..2]).to eq santander.cod_banco # cod. do banco + expect(header[16]).to eq '2' # tipo inscricao do cedente + expect(header[18..31]).to eq '28254225000193' # documento do cedente + expect(header[32..71]).to eq santander.codigo_convenio # informacoes do convenio + expect(header[72..101]).to eq 'SOCIEDADE BRASILEIRA DE ZOOLOG' # razao social do cedente + expect(header[157..162]).to eq '000001' # sequencial de remessa + expect(header[163..165]).to eq santander.versao_layout_arquivo # versao do layout + end + end + + context 'header lote' do + it 'header lote deve ter 240 posicoes' do + expect(santander.monta_header_lote(1).size).to eq 240 + end + + it 'header lote deve ter as informacoes nas posicoes corretas' do + header = santander.monta_header_lote(1) + expect(header[0..2]).to eq santander.cod_banco # cod. do banco + expect(header[3..6]).to eq '0001' # numero do lote + expect(header[13..15]).to eq santander.versao_layout_lote # versao do layout + expect(header[17]).to eq '2' # tipo inscricao do cedente + expect(header[18..32]).to eq '028254225000193' # documento do cedente + expect(header[33..72]).to eq santander.convenio_lote # informacoes do convenio + expect(header[73..102]).to eq 'SOCIEDADE BRASILEIRA DE ZOOLOG' # razao social do cedente + expect(header[103..142]).to eq ''.rjust(40, ' ') # 1a mensagem + expect(header[143..182]).to eq ''.rjust(40, ' ') # 2a mensagem + expect(header[183..190]).to eq '00000001' # sequencial de remessa + end + end + + + context 'segmento P' do + it 'segmento P deve ter 240 posicoes' do + expect(santander.monta_segmento_p(pagamento, 1, 2).size).to eq 240 + end + + it 'segmento P deve ter as informacos nas posicoes corretas' do + segmento_p = santander.monta_segmento_p(pagamento, 1, 2) + expect(segmento_p[0..2]).to eq santander.cod_banco # codigo do banco + expect(segmento_p[3..6]).to eq '0001' # numero do lote + expect(segmento_p[8..12]).to eq '00002' # sequencial do registro no lote + expect(segmento_p[17..20]).to eq santander.agencia # agencia + expect(segmento_p[21]).to eq santander.digito_agencia.to_s # digito da agencia + expect(segmento_p[22..56]).to eq santander.complemento_p(pagamento) # complemento do segmento P + expect(segmento_p[62..76]).to eq '9999 ' # numero do documento + expect(segmento_p[77..84]).to eq Date.current.strftime('%d%m%Y') # data de vencimento + expect(segmento_p[85..99]).to eq '000000000019990' # valor + expect(segmento_p[109..116]).to eq Date.current.strftime('%d%m%Y') # data de emissao + expect(segmento_p[141]).to eq '0' # codigo do desconto + expect(segmento_p[142..149]).to eq '00000000' # data de desconto + expect(segmento_p[150..164]).to eq ''.rjust(15, '0') # valor do desconto + expect(segmento_p[165..179]).to eq ''.rjust(15, '0') # valor do IOF + expect(segmento_p[180..194]).to eq ''.rjust(15, '0') # valor do abatimento + end + + it 'segmento P deve ter as informações sobre o protesto' do + pagamento.codigo_protesto = '3' + pagamento.dias_protesto = '6' + segmento_p = santander.monta_segmento_p(pagamento, 1, 2) + + expect(segmento_p[220]).to eq '3' + expect(segmento_p[221..222]).to eq '06' + end + end + + context 'segmento Q' do + it 'segmento Q deve ter 240 posicoes' do + expect(santander.monta_segmento_q(pagamento, 1, 3).size).to eq 240 + end + + it 'segmento Q deve ter as informacoes nas posicoes corretas' do + segmento_q = santander.monta_segmento_q(pagamento, 1, 3) + expect(segmento_q[0..2]).to eq santander.cod_banco # codigo do banco + expect(segmento_q[3..6]).to eq '0001' # numero do lote + expect(segmento_q[8..12]).to eq '00003' # numero do registro no lote + expect(segmento_q[17]).to eq '1' # tipo inscricao sacado + expect(segmento_q[18..32]).to eq '000012345678901' # documento do sacado + expect(segmento_q[33..72]).to eq 'PABLO DIEGO JOSE FRANCISCO DE PAULA JUAN' # nome do sacado + expect(segmento_q[73..112]).to eq 'RUA RIO GRANDE DO SUL Sao paulo Minas ca' # endereco do sacado + expect(segmento_q[113..127]).to eq 'Sao jose dos qu' # bairro do sacado + expect(segmento_q[128..132]).to eq '12345' # CEP do sacado + expect(segmento_q[133..135]).to eq '678' # sufixo CEP do sacado + expect(segmento_q[136..150]).to eq 'Santa rita de c' # cidade do sacado + expect(segmento_q[151..152]).to eq 'SP' # UF do sacado + end + end + + context 'segmento R' do + it 'segmento R deve ter 240 posicoes' do + expect(santander.monta_segmento_r(pagamento, 1, 4).size).to eq 240 + end + + it 'segmento R deve ter as informacoes nas posicoes corretas' do + segmento_r = santander.monta_segmento_r(pagamento, 1, 4) + expect(segmento_r[0..2]).to eq santander.cod_banco # codigo banco + expect(segmento_r[3..6]).to eq '0001' # lote de servico + expect(segmento_r[7]).to eq '3' # tipo de registro + expect(segmento_r[8..12]).to eq '00004' # nro seq. registro no lote + expect(segmento_r[13]).to eq 'R' # cod. segmento + expect(segmento_r[14]).to eq ' ' # branco + expect(segmento_r[15..16]).to eq '01' # cod. movimento remessa + expect(segmento_r[17..40]).to eq ''.rjust(24, '0') # desconto 2 + expect(segmento_r[41..64]).to eq ''.rjust(24, '0') # desconto 3 + expect(segmento_r[65]).to eq '0' # cod. multa + expect(segmento_r[66..73]).to eq ''.rjust(8, '0') # data multa + expect(segmento_r[74..88]).to eq ''.rjust(15, '0') # valor multa + expect(segmento_r[89..98]).to eq ''.rjust(10, ' ') # info pagador + expect(segmento_r[99..138]).to eq ''.rjust(40, ' ') # mensagem 3 + expect(segmento_r[139..178]).to eq ''.rjust(40, ' ') # mensagem 4 + expect(segmento_r[179..239]).to eq santander.complemento_r # complemento do segmento + end + end + + context 'trailer lote' do + it 'trailer lote deve ter 240 posicoes' do + expect(santander.monta_trailer_lote(1, 4).size).to eq 240 + end + + it 'trailer lote deve ter as informacoes nas posicoes corretas' do + trailer = santander.monta_trailer_lote(1, 4) + expect(trailer[0..2]).to eq santander.cod_banco # cod. do banco + expect(trailer[3..6]).to eq '0001' # numero do lote + expect(trailer[17..22]).to eq '000004' # qtde de registros no lote + expect(trailer[23..239]).to eq santander.complemento_trailer # complemento do registro trailer + end + end + + context 'trailer arquivo' do + it 'trailer arquivo deve ter 240 posicoes' do + expect(santander.monta_trailer_arquivo(1, 6).size).to eq 240 + end + + it 'trailer arquivo deve ter as informacoes nas posicoes corretas' do + trailer = santander.monta_trailer_arquivo(1, 6) + expect(trailer[0..2]).to eq santander.cod_banco # cod. do banco + expect(trailer[17..22]).to eq '000001' # qtde de lotes + expect(trailer[23..28]).to eq '000006' # qtde de registros + end + end + + context 'monta lote' do + it 'retorno de lote deve ser uma colecao com os registros' do + lote = santander.monta_lote(1) + + expect(lote.is_a?(Array)).to be true + expect(lote.count).to be 5 # header, segmento p, segmento q, segmento r e trailer + end + + it 'contador de registros deve acrescer 1 a cada registro' do + lote = santander.monta_lote(1) + + expect(lote[1][8..12]).to eq '00001' # segmento P + expect(lote[2][8..12]).to eq '00002' # segmento Q + expect(lote[3][8..12]).to eq '00003' # segmento R + expect(lote[4][17..22]).to eq '000005' # trailer do lote + end + end + + context 'gera arquivo' do + it 'deve falhar se o objeto for invalido' do + expect { subject.class.new.gera_arquivo }.to raise_error(Brcobranca::RemessaInvalida) + end + + it 'remessa deve conter os registros mais as quebras de linha' do + remessa = santander.gera_arquivo + + expect(remessa.size).to eq 1694 + # quebras de linha + expect(remessa[240..241]).to eq "\r\n" + expect(remessa[482..483]).to eq "\r\n" + expect(remessa[724..725]).to eq "\r\n" + expect(remessa[966..967]).to eq "\r\n" + expect(remessa[1208..1209]).to eq "\r\n" + end + + it { expect(santander.gera_arquivo).to eq(read_remessa('remessa-santander-cnab240.rem', santander.gera_arquivo)) } + end + end +end diff --git a/spec/fixtures/remessa/remessa-santander-cnab240.rem b/spec/fixtures/remessa/remessa-santander-cnab240.rem new file mode 100644 index 00000000..45b84e08 --- /dev/null +++ b/spec/fixtures/remessa/remessa-santander-cnab240.rem @@ -0,0 +1,7 @@ +03300000 2028254225000193000100001234567 SOCIEDADE BRASILEIRA DE ZOOLOGBANCO SANTANDER 114072015 000001040 +03300011R01 030 2028254225000193 000100001234567 SOCIEDADE BRASILEIRA DE ZOOLOG 000000011407201500000000 +0330001300001P 010001301300123410130012341 0000012345679112 9999 1407201500000000001999000000 02N140720153000000000000000000000000000000000000000000000000000000000000000000000000000009999 300300000 +0330001300002Q 011000012345678901PABLO DIEGO JOSE FRANCISCO DE PAULA JUANRUA RIO GRANDE DO SUL SAO PAULO MINAS CASAO JOSE DOS QU12345678SANTA RITA DE CSP0000000000000000 000000000000 +0330001300003R 01000000000000000000000000000000000000000000000000000000000000000000000000 +03300015 000005 +03399999 000001000007