BoletoNet / boletonet

Boleto.Net is a library developed for use in Brazil, given it has been programmed with Brazilian retail legislation and business rules for bank registered billing integration.
Apache License 2.0
480 stars 383 forks source link

"Banco" Daycoval e Sofisa #521

Open carlsonrocha opened 7 years ago

carlsonrocha commented 7 years ago

Bom dia, Vocês já implementaram os referidos bancos acima? Navegando os fontes vi no nome deles, mas não ví nada na documentação.

Eles na verdade não são bancos, o sofisa usa como base a estrutura do Santander e o daycoval usa do itaú.

carloscds commented 7 years ago

@carlsonrocha Sofisa tem sim! Daycoval não!

rodolfoghi commented 7 years ago

O Banco Daycoval não é implementado por esta classe? Falta homologar, é isso?

diegomodolo commented 7 years ago

Olá pessoal, desculpe a demora em responder. Eu que implementei Sofisa e Daycoval. Precisei fazer algumas alterações na remessa de um deles, mas fiz localmente. Vou tentar enviar o PR o mais rápido possível. Para as minhas necessidades está homologado, meu cliente tem emitido boleto para estes bancos desde janeiro, mas pode ser que para outras empresas seja necessário fazer alterações.

rodolfoghi commented 7 years ago

@diegomodolo temos um cliente que está precisando do banco Daycoval com urgência, tens ideia de quando irás fazer o PR? Caso consigas fazer ainda hoje, no máximo amanhã, agradecemos, senão teremos que implementar algo que provavelmente você já implementou.

diegomodolo commented 7 years ago

@rodolfoghi, estou tentando fazer o PR desde cedo, mas não sou muito familiarizado com Git e estou apanhando bastante. Mas a alteração que fiz foi no Sofisa, o Daycoval está OK.

carlsonrocha commented 7 years ago

meu cliente também precisa. Há alguma precisão?

-- Atenciosamente,


          CARLSON ROCHA

Em 12 de julho de 2017 14:29, Diego Modolo Ribeiro <notifications@github.com

escreveu:

@rodolfoghi https://github.com/rodolfoghi, estou tentando fazer o PR desde cedo, mas não sou muito familiarizado com Git e estou apanhando bastante. Mas a alteração que fiz foi no Sofisa, o Daycoval está OK.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BoletoNet/boletonet/issues/521#issuecomment-314840177, or mute the thread https://github.com/notifications/unsubscribe-auth/ABSqUg5qd7XGa7aTtyzOmo1_miuCWCewks5sNQJhgaJpZM4OIXLW .

diegomodolo commented 7 years ago

Boa tarde,

Daycoval já está homologado. Estou no cliente que o utiliza agora e eles me confirmaram que tem emitido boletos Daycoval e Sofisa há bastante tempo. O único problema do Sofisa é que o arquivo de remessa estava com problemas, eu já arrumei mas não consigo fazer PR. Utilizo apenas TFS nos meus projetos e não tenho nenhuma familiaridade com o GitHub. Estou enviando o código fonte do arquivo abaixo, caso alguém consiga fazer sinta-se bem vindo.

Att,

// -------------------------------------------------------------------------------------------------------------------- // // Boleto.Net // //

// Defines the Banco_Sofisa.cs type. // // --------------------------------------------------------------------------------------------------------------------

using System.Web.UI;

[assembly: WebResource("BoletoNet.Imagens.637.jpg", "image/jpg")]

namespace BoletoNet { using System; using System.Text;

         using global::BoletoNet.Excecoes;
         using global::BoletoNet.Util;

         internal class Banco_Sofisa : AbstractBanco, IBanco
         {
                       private IBanco _banco;

                       private string _convenio = string.Empty;

                       #region Constructors and Destructors

                       internal Banco_Sofisa()
                       {
                                    this.Codigo = 637;
                                    this.Digito = "0";
                                    this.Nome = "Sofisa";
                       }

                       #endregion

                       #region Public Methods and Operators

                       public override void FormataNossoNumero(Boleto boleto)
                       {
                                    if (boleto.NossoNumero.Length > 12)
                                    {
                                                  throw new TamanhoNossoNumeroInvalidoException(12);
                                    }

                                    base.FormataNossoNumero(boleto);
                       }

                       public override string GerarDetalheRemessa(Boleto boleto, int numeroRegistro, TipoArquivo tipoArquivo)
                       {
                                    try
                                    {
                                                  var detalhe = string.Empty;

                                                  switch (tipoArquivo)
                                                  {
                                                               case TipoArquivo.CNAB240:
                                                                             break;
                                                               case TipoArquivo.CNAB400:
                                                                             detalhe = this.GerarDetalheRemessaCNAB400(boleto, numeroRegistro);
                                                                             break;
                                                               case TipoArquivo.CBR643:
                                                                             break;
                                                               case TipoArquivo.Outro:
                                                                             break;
                                                               default:
                                                                             throw new ArgumentOutOfRangeException("tipoArquivo", tipoArquivo, null);
                                                  }

                                                  return detalhe;
                                    }
                                    catch (Exception)
                                    {
                                                  throw;
                                    }
                       }

                       public override string GerarHeaderRemessa(
                                    string numeroConvenio,
                                    Cedente cedente,
                                    TipoArquivo tipoArquivo,
                                    int numeroArquivoRemessa)
                       {
                                    try
                                    {
                                                  this._convenio = numeroConvenio;

                                                  this.Cedente = cedente;

                                                  var header = string.Empty;

                                                 base.GerarHeaderRemessa(numeroConvenio, cedente, tipoArquivo, numeroArquivoRemessa);

                                                  switch (tipoArquivo)
                                                  {
                                                               case TipoArquivo.CNAB240:
                                                                             break;
                                                               case TipoArquivo.CNAB400:
                                                                             header = this.GerarHeaderRemessaCNAB400(numeroConvenio);
                                                                             break;
                                                               case TipoArquivo.CBR643:
                                                                             break;
                                                               case TipoArquivo.Outro:
                                                                             break;
                                                               default:
                                                                             throw new ArgumentOutOfRangeException("tipoArquivo", tipoArquivo, null);
                                                  }

                                                  return header;
                                    }
                                    catch (Exception)
                                    {
                                                  throw;
                                    }
                       }

                       public override string GerarTrailerRemessa(
                                    int numeroRegistro,
                                    TipoArquivo tipoArquivo,
                                    Cedente cedente,
                                    decimal vltitulostotal)
                       {
                                    try
                                    {
                                                  var trailer = string.Empty;

                                                 base.GerarTrailerRemessa(numeroRegistro, tipoArquivo, cedente, vltitulostotal);

                                                  switch (tipoArquivo)
                                                  {
                                                               case TipoArquivo.CNAB240:
                                                                             break;
                                                               case TipoArquivo.CNAB400:
                                                                             trailer = this.GerarTrailerRemessa400(numeroRegistro);
                                                                             break;
                                                               case TipoArquivo.Outro:
                                                                             break;
                                                               default:
                                                                             throw new ArgumentOutOfRangeException("tipoArquivo", tipoArquivo, null);
                                                  }

                                                  return trailer;
                                    }
                                    catch (Exception)
                                    {
                                                  throw;
                                    }
                       }

                       public override DetalheRetorno LerDetalheRetornoCNAB400(string registro)
                       {
                                    var detalheRetorno = new DetalheRetorno();

                                    detalheRetorno.IdentificacaoDoRegistro = Utils.ToInt32(registro.Substring(0, 1));
                                    detalheRetorno.CodigoInscricao = Utils.ToInt32(registro.Substring(1, 2));
                                    detalheRetorno.NumeroInscricao = registro.Substring(3, 14);
                                    detalheRetorno.UsoEmpresa = registro.Substring(37, 25);
                                    detalheRetorno.Carteira = registro.Substring(82, 3);
                                    detalheRetorno.NossoNumero = registro.Substring(94, 11);
                                    detalheRetorno.NossoNumeroComDV = registro.Substring(94, 12);
                                    detalheRetorno.Carteira = registro.Substring(107, 1);
                                    detalheRetorno.CodigoOcorrencia = int.Parse(registro.Substring(108, 2));

                                    var dataOcorrencia = Utils.ToInt32(registro.Substring(110, 6));
                                    detalheRetorno.DataOcorrencia = Utils.ToDateTime(dataOcorrencia.ToString("##-##-##"));

                                    detalheRetorno.SeuNumero = registro.Substring(116, 10);

                                    detalheRetorno.NumeroDocumento = detalheRetorno.SeuNumero;

                                    var dataVencimento = Utils.ToInt32(registro.Substring(146, 6));
                                    detalheRetorno.DataVencimento = Utils.ToDateTime(dataVencimento.ToString("##-##-##"));

                                    decimal valorTitulo = Convert.ToInt64(registro.Substring(152, 13));
                                    detalheRetorno.ValorTitulo = valorTitulo / 100;

                                    detalheRetorno.CodigoBanco = Utils.ToInt32(registro.Substring(165, 3));
                                    detalheRetorno.AgenciaCobradora = Utils.ToInt32(registro.Substring(168, 5));
                                    detalheRetorno.Especie = Utils.ToInt32(registro.Substring(173, 2));

                                    decimal valorDespesa = Convert.ToUInt64(registro.Substring(175, 13));
                                    detalheRetorno.ValorDespesa = valorDespesa / 100;

                                    decimal valorIof = Convert.ToUInt64(registro.Substring(214, 11));
                                    detalheRetorno.IOF = valorIof / 100;

                                    decimal valorAbatimento = Convert.ToUInt64(registro.Substring(227, 11));
                                    detalheRetorno.ValorAbatimento = valorAbatimento / 100;

                                    decimal valorDesconto = Convert.ToUInt64(registro.Substring(240, 11));
                                    detalheRetorno.Descontos = valorDesconto / 100;

                                    decimal valorPago = Convert.ToUInt64(registro.Substring(253, 13));
                                    detalheRetorno.ValorPago = valorPago / 100;

                                    decimal jurosMora = Convert.ToUInt64(registro.Substring(266, 13));
                                    detalheRetorno.JurosMora = jurosMora / 100;

                                    var dataCredito = Convert.ToUInt64(registro.Substring(385, 6));

                                    detalheRetorno.DataCredito = Utils.ToDateTime(dataCredito.ToString("##-##-##"));

                                    return detalheRetorno;
                       }

                       public override void ValidaBoleto(Boleto boleto)
                       {
                                    if (this._banco == null && this.Codigo != boleto.Banco.Codigo)
                                    {
                                                  this._banco = boleto.Banco;
                                    }
                                    else
                                    {
                                                  // Por padrão o Daycoval utiliza o layout do Bradesco,
                                                  // porém é apto a trabalhar com outros bancos,
                                                  // por isso a validação acima.
                                                  this._banco = new Banco_Bradesco();
                                    }

                                    this._banco.ValidaBoleto(boleto);
                       }

                       #endregion

                       #region Methods

                       private string GerarDetalheRemessaCNAB400(Boleto boleto, int numeroRegistro)
                       {
                                    var detalhe = new StringBuilder();

                                    detalhe.Append("1"); // Identificação do registro, sempre 1

                                    // Identificação do tipo de inscrição da empresa
                                    // 01 - CPF do cedente
                                    // 02 - CNPJ do cedente
                                    // 03 - CPF do Sacador
                                    // 04 - CNPJ Sacador
                                    detalhe.Append(boleto.Cedente.CPFCNPJ.Length == 11 ? "01" : "02");

                                    // CPF/CNPJ da empresa ou sacador
                                    detalhe.Append(Utils.FitStringLength(boleto.Cedente.CPFCNPJ, 14, 14, '0', 0, true, true, true));

                                    // Código da empresea, fornecido pelo banco
                                    detalhe.Append(Utils.FitStringLength(this._convenio, 20, 20, ' ', 0, true, true, false));

                                    // Número do documento interno
                                    detalhe.Append(Utils.FitStringLength(boleto.NumeroDocumento, 25, 25, ' ', 0, true, true, false));

                                    // Nosso número, sempre 0
                                    detalhe.Append(Utils.FitStringLength(string.Empty, 8, 8, '0', 0, true, true, true));

                                    // Nosso número do correspondente, mesmo do boleto
                                    detalhe.Append(Utils.FitStringLength(boleto.NossoNumero, 12, 12, '0', 0, true, true, true));

                                    // Nosso número do correspondente, mesmo do boleto
                                    if (this._banco == null)
                                    {
                                                  this._banco = boleto.Banco;
                                    }

                                    this._banco.ValidaBoleto(boleto);

                                    detalhe.Append(boleto.DigitoNossoNumero);

                                    // Uso do banco
                                    detalhe.Append(Utils.FitStringLength(string.Empty, 24, 24, ' ', 0, true, true, false));
                                    detalhe.Append("4"); // TODO: Código de remessa
                                    detalhe.Append("01"); // TODO: Código de ocorrência
                                    // Seu número
                                    detalhe.Append(Utils.FitStringLength(boleto.NumeroDocumento, 10, 10, ' ', 0, true, true, false));
                                    detalhe.Append(boleto.DataVencimento.ToString("ddMMyy"));
                                    detalhe.Append(Utils.FitStringLength(boleto.ValorBoleto.ApenasNumeros(), 13, 13, '0', 0, true, true, true));
                                    detalhe.Append("237"); // Código do banco
                                    detalhe.Append(Utils.FitStringLength(string.Empty, 4, 4, '0', 0, true, true, true)); // Agência cobradora
                                    detalhe.Append("0"); // DAC da agência cobradora
                                    detalhe.Append(Utils.FitStringLength(boleto.EspecieDocumento.Codigo, 2, 2, '0', 0, true, true, true));
                                    detalhe.Append("N"); // Indicação de aceite do título, sempre N
                                    detalhe.Append(boleto.DataDocumento.ToString("ddMMyy"));
                                    detalhe.Append(Utils.FitStringLength(string.Empty, 4, 4, '0', 0, true, true, true)); // Zeros
                                    detalhe.Append(Utils.FitStringLength(boleto.JurosMora.ApenasNumeros(), 13, 13, '0', 0, true, true, true));
                                    detalhe.Append(boleto.DataDesconto == DateTime.MinValue ? "000000" : boleto.DataDesconto.ToString("ddMMyy"));
                                    detalhe.Append(Utils.FitStringLength(boleto.ValorDesconto.ApenasNumeros(), 13, 13, '0', 0, true, true, true));
                                    detalhe.Append(Utils.FitStringLength(boleto.IOF.ApenasNumeros(), 13, 13, '0', 0, true, true, true));
                                    detalhe.Append(Utils.FitStringLength(boleto.Abatimento.ApenasNumeros(), 13, 13, '0', 0, true, true, true));

                                    detalhe.Append(boleto.Sacado.CPFCNPJ.Length == 11 ? "01" : "02");
                                    detalhe.Append(Utils.FitStringLength(boleto.Sacado.CPFCNPJ, 14, 14, '0', 0, true, true, true));
                                    detalhe.Append(
                                                 Utils.SubstituiCaracteresEspeciais(Utils.FitStringLength(boleto.Sacado.Nome, 30, 30, ' ', 0, true, true, false)));
                                    detalhe.Append(Utils.FitStringLength(string.Empty, 10, 10, ' ', 0, true, true, false));
                                    detalhe.Append(
                                                 Utils.SubstituiCaracteresEspeciais(
                                                               Utils.FitStringLength(boleto.Sacado.Endereco.Logradouro, 40, 40, ' ', 0, true, true, false)));
                                    detalhe.Append(
                                                 Utils.SubstituiCaracteresEspeciais(
                                                               Utils.FitStringLength(boleto.Sacado.Endereco.Bairro, 12, 12, ' ', 0, true, true, false)));
                                    detalhe.Append(Utils.FitStringLength(boleto.Sacado.Endereco.CEP, 8, 8, '0', 0, true, true, true));
                                    detalhe.Append(
                                                 Utils.SubstituiCaracteresEspeciais(
                                                               Utils.FitStringLength(boleto.Sacado.Endereco.Cidade, 15, 15, ' ', 0, true, true, false)));
                                    detalhe.Append(Utils.FitStringLength(boleto.Sacado.Endereco.UF, 2, 2, ' ', 0, true, true, false));
                                    detalhe.Append(Utils.FitStringLength(boleto.Avalista != null ? boleto.Avalista.Nome : string.Empty, 30, 30, ' ', 0, true, true, false));
                                    detalhe.Append(Utils.FitStringLength(string.Empty, 10, 10, ' ', 0, true, true, false)); // Brancos
                                    detalhe.Append("00"); // Dias para início do protesto
                                    detalhe.Append(boleto.Moeda == 9 ? 0 : 2);
                                    detalhe.Append(Utils.FitStringLength(numeroRegistro.ToString(), 6, 6, '0', 0, true, true, true));

                                    var detalheFormatado = detalhe.ToString();

                                    if (detalheFormatado.Length != 400)
                                    {
                                                  throw new Exception("Tamanho do registro inválido.");
                                    }

                                    return detalheFormatado;
                       }

                       private string GerarHeaderRemessaCNAB400(string convenio)
                       {
                                    var header = new StringBuilder();

                                    header.Append("0"); // Identificação do registro header, sempre 0
                                    header.Append("1"); // Código da remessa, sempre 1
                                    header.Append("REMESSA"); // Literal de remessa
                                    header.Append("01"); // Código do serviço, sempre 01

                                    // Identificação por extenso do tipo de serviço
                                    header.Append(Utils.FitStringLength("COBRANCA", 15, 15, ' ', 0, true, true, false));

                                    // Código da empresa, fornecido pelo banco
                                    header.Append(Utils.FitStringLength(convenio, 20, 20, ' ', 0, true, true, false));
                                    header.Append(Utils.FitStringLength(this.Cedente.Nome, 30, 30, ' ', 0, true, true, false)); // Nome do cedente
                                    header.Append("637"); // Código do banco
                                    header.Append(Utils.FitStringLength("BANCO SOFISA SA", 15, 15, ' ', 0, true, true, false)); // Nome do banco
                                    header.Append(DateTime.Now.ToString("ddMMyy")); // Data
                                    header.Append(Utils.FitStringLength(string.Empty, 294, 294, ' ', 0, true, true, false));
                                    header.Append("000001"); // Sequencial, sempre 1

                                    var headerFormatado = Utils.SubstituiCaracteresEspeciais(header.ToString());

                                    return headerFormatado;
                       }

                       private string GerarTrailerRemessa400(int numeroRegistro)
                       {
                                    try
                                    {
                                                  var complemento = new string(' ', 393);
                                                  var trailer = new StringBuilder();

                                                  trailer.Append("9");
                                                 trailer.Append(complemento);
                                                 trailer.Append(Utils.FitStringLength(numeroRegistro.ToString(), 6, 6, '0', 0, true, true, true));

                                                  // Número sequencial do registro no arquivo.
                                                  var trailerFormatado = Utils.SubstituiCaracteresEspeciais(trailer.ToString());

                                                  return trailerFormatado;
                                    }
                                    catch (Exception ex)
                                    {
                                                  throw new Exception("Erro durante a geração do registro TRAILER do arquivo de REMESSA.", ex);
                                    }
                       }

                       #endregion
         }

}

Enviado do Emailhttps://go.microsoft.com/fwlink/?LinkId=550986 para Windows 10

De: Carlson Rochamailto:notifications@github.com Enviado:quinta-feira, 13 de julho de 2017 15:08 Para: BoletoNet/boletonetmailto:boletonet@noreply.github.com Cc:Diego Modolo Ribeiromailto:diego.ribeiro@nectarnet.com.br; Mentionmailto:mention@noreply.github.com Assunto: Re: [BoletoNet/boletonet] "Banco" Daycoval e Sofisa (#521)

meu cliente também precisa. Há alguma precisão?

-- Atenciosamente,


CARLSON ROCHA

Em 12 de julho de 2017 14:29, Diego Modolo Ribeiro <notifications@github.com

escreveu:

@rodolfoghi https://github.com/rodolfoghi, estou tentando fazer o PR desde cedo, mas não sou muito familiarizado com Git e estou apanhando bastante. Mas a alteração que fiz foi no Sofisa, o Daycoval está OK.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BoletoNet/boletonet/issues/521#issuecomment-314840177, or mute the thread https://github.com/notifications/unsubscribe-auth/ABSqUg5qd7XGa7aTtyzOmo1_miuCWCewks5sNQJhgaJpZM4OIXLW .

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/BoletoNet/boletonet/issues/521#issuecomment-315157848, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ALtGPfzUa5Cr5KiHPmkUPfHxsgwuEHngks5sNl0ygaJpZM4OIXLW.