public void TestGerarHeaderArquivoRemessaBRBCnab400()
        {
            var dadosRemessa = new Remessa(Remessa.EnumTipoAmbiemte.Homologacao, EnumCodigoOcorrenciaRemessa.Registro,
                "");
            var banco = Fabricas.BancoFactory.ObterBanco("070");
            var contaBancariaCedente = new ContaBancaria("201", "", "29088", "1");
            var cedente = new Cedente("99999", 0, "99.999.999/9999-99", "Razão Social X", contaBancariaCedente, null);
            var sacado = new Sacado("Sacado Fulano de Tal", "99.999.999/9999-99", new Endereco()
            {
                TipoLogradouro = "R",
                Logradouro = "1",
                Bairro = "Bairro X",
                Cidade = "Cidade X",
                SiglaUf = "XX",
                Cep = "12345-000",
                Complemento = "Comp X",
                Numero = "9"
            });

            var carteira = new CarteiraCobranca {Codigo = "1", Tipo = "1"};

            var boleto = new Boleto(carteira, cedente, sacado, dadosRemessa)
            {
                NumeroDocumento = "279141",
                ValorBoleto = Convert.ToDecimal(222.75),
                IdentificadorInternoBoleto = "279141",
                DataVencimento = new DateTime(2015, 03, 16),
                Especie = banco.ObtemEspecieDocumento(EnumEspecieDocumento.Diversos),
                CodigoOcorrenciaRemessa = new CodigoOcorrencia(01),
                BancoBoleto = banco,
                TipoCobrancaJuro = TipoCobrancaJuro.JurosDiario
            };

            banco.FormatarBoleto(boleto);

            var remessa = new RemessaCnab400();

            remessa.Header = new HeaderRemessaCnab400(boleto, 1, 1, DateTime.Now);
            var detalheIndividual = new DetalheRemessaCnab400(boleto, 1);
            remessa.RegistrosDetalhe = new List<DetalheRemessaCnab400>
            {
                detalheIndividual
            };
            var escritor = new EscritorRemessaCnab400BRB(remessa);

            var linhasEscrever = escritor.EscreverTexto(remessa);
            var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            var data = String.Format("{0}_{1}", DateTime.Now.ToString("ddMMyyyy"), DateTime.Now.ToString("HHmmss"));

            var nomeArquivo = string.Format("{0}{1}{2}{3}", banco.CodigoBanco, @"_REMESSA_", data, ".txt");
            var arquivo = new System.IO.StreamWriter(path + @"\" + nomeArquivo, true);

            foreach (var linha in linhasEscrever)
            {
                arquivo.WriteLine(linha);
            }
            arquivo.Close();
        }
        public void AdicionarBoleto(Boleto boletoAdicionar, int numeroSequencialRegistro)
        {
            if (boletoAdicionar.BancoBoleto == null)
            {
                throw new ValidacaoBoletoException("Boleto " + boletoAdicionar.NossoNumeroFormatado +
                                                   " não é válido para adição na remessa. Falta informar o banco do boleto.");
            }

            if (boletoAdicionar.CarteiraCobranca == null)
            {
                throw new ValidacaoBoletoException("Boleto " + boletoAdicionar.NossoNumeroFormatado +
                                                   " não é válido para adição na remessa. Falta informar a carteira de cobrança.");
            }

            var detalheRemessaAdicionar = new DetalheRemessaCnab400(boletoAdicionar, numeroSequencialRegistro);

            //detalheRemessaAdicionar.CodigoBanco = boletoAdicionar.BancoBoleto.CodigoBanco;
            //detalheRemessaAdicionar.Agencia = boletoAdicionar.CedenteBoleto.ContaBancariaCedente.Agencia;
            //detalheRemessaAdicionar.DvAgencia = boletoAdicionar.CedenteBoleto.ContaBancariaCedente.DigitoAgencia;
            //detalheRemessaAdicionar.ContaCorrente = boletoAdicionar.CedenteBoleto.ContaBancariaCedente.Conta;
            //detalheRemessaAdicionar.DvContaCorrente = boletoAdicionar.CedenteBoleto.ContaBancariaCedente.DigitoConta;

            //detalheRemessaAdicionar.CodigoCedente = boletoAdicionar.CedenteBoleto.CodigoCedente;
            //detalheRemessaAdicionar.NossoNumero = boletoAdicionar.NossoNumeroFormatado;
            //detalheRemessaAdicionar.DvNossoNumero = boletoAdicionar.DigitoNossoNumero;
            //detalheRemessaAdicionar.NumeroDocumento = boletoAdicionar.NumeroDocumento;
            //detalheRemessaAdicionar.DataVencimento = boletoAdicionar.DataVencimento;
            //detalheRemessaAdicionar.DataEmissao = boletoAdicionar.DataDocumento;

            //detalheRemessaAdicionar.CodigoOcorrencia = boletoAdicionar.CodigoOcorrenciaRemessa;
            //detalheRemessaAdicionar.Especie = boletoAdicionar.Especie;
            //detalheRemessaAdicionar.Aceite = boletoAdicionar.Aceite;

            //detalheRemessaAdicionar.ValorBoleto = boletoAdicionar.ValorBoleto;
            //detalheRemessaAdicionar.ValorDesconto = boletoAdicionar.ValorDesconto;
            //detalheRemessaAdicionar.ValorIof = boletoAdicionar.Iof;
            //detalheRemessaAdicionar.ValorAbatimento = boletoAdicionar.ValorAbatimento;

            //detalheRemessaAdicionar.InscricaoPagador = boletoAdicionar.SacadoBoleto.CpfCnpj;
            //detalheRemessaAdicionar.NomePagador = boletoAdicionar.SacadoBoleto.Nome;
            //detalheRemessaAdicionar.EnderecoPagador =
            //    boletoAdicionar.SacadoBoleto.EnderecoSacado.LogradouroNumeroComplementoConcatenado;
            //detalheRemessaAdicionar.CidadePagador = boletoAdicionar.SacadoBoleto.EnderecoSacado.Cidade;
            //detalheRemessaAdicionar.UfPagador = boletoAdicionar.SacadoBoleto.EnderecoSacado.SiglaUf;
            //detalheRemessaAdicionar.CepPagador = boletoAdicionar.SacadoBoleto.EnderecoSacado.Cep;
            //detalheRemessaAdicionar.NumeroSequencialRegistro = numeroSequencialRegistro;
        }
        public void AdicionarBoleto(Boleto boletoAdicionar, int numeroSequencialRegistro)
        {
            if (boletoAdicionar.BancoBoleto == null)
                throw new ValidacaoBoletoException("Boleto " + boletoAdicionar.NossoNumeroFormatado +
                                                   " não é válido para adição na remessa. Falta informar o banco do boleto.");

            if (boletoAdicionar.CarteiraCobranca == null)
                throw new ValidacaoBoletoException("Boleto " + boletoAdicionar.NossoNumeroFormatado +
                                                   " não é válido para adição na remessa. Falta informar a carteira de cobrança.");

            var detalheRemessaAdicionar = new DetalheRemessaCnab400(boletoAdicionar, numeroSequencialRegistro);

            //detalheRemessaAdicionar.CodigoBanco = boletoAdicionar.BancoBoleto.CodigoBanco;
            //detalheRemessaAdicionar.Agencia = boletoAdicionar.CedenteBoleto.ContaBancariaCedente.Agencia;
            //detalheRemessaAdicionar.DvAgencia = boletoAdicionar.CedenteBoleto.ContaBancariaCedente.DigitoAgencia;
            //detalheRemessaAdicionar.ContaCorrente = boletoAdicionar.CedenteBoleto.ContaBancariaCedente.Conta;
            //detalheRemessaAdicionar.DvContaCorrente = boletoAdicionar.CedenteBoleto.ContaBancariaCedente.DigitoConta;

            //detalheRemessaAdicionar.CodigoCedente = boletoAdicionar.CedenteBoleto.CodigoCedente;
            //detalheRemessaAdicionar.NossoNumero = boletoAdicionar.NossoNumeroFormatado;
            //detalheRemessaAdicionar.DvNossoNumero = boletoAdicionar.DigitoNossoNumero;
            //detalheRemessaAdicionar.NumeroDocumento = boletoAdicionar.NumeroDocumento;
            //detalheRemessaAdicionar.DataVencimento = boletoAdicionar.DataVencimento;
            //detalheRemessaAdicionar.DataEmissao = boletoAdicionar.DataDocumento;

            //detalheRemessaAdicionar.CodigoOcorrencia = boletoAdicionar.CodigoOcorrenciaRemessa;
            //detalheRemessaAdicionar.Especie = boletoAdicionar.Especie;
            //detalheRemessaAdicionar.Aceite = boletoAdicionar.Aceite;

            //detalheRemessaAdicionar.ValorBoleto = boletoAdicionar.ValorBoleto;
            //detalheRemessaAdicionar.ValorDesconto = boletoAdicionar.ValorDesconto;
            //detalheRemessaAdicionar.ValorIof = boletoAdicionar.Iof;
            //detalheRemessaAdicionar.ValorAbatimento = boletoAdicionar.ValorAbatimento;

            //detalheRemessaAdicionar.InscricaoPagador = boletoAdicionar.SacadoBoleto.CpfCnpj;
            //detalheRemessaAdicionar.NomePagador = boletoAdicionar.SacadoBoleto.Nome;
            //detalheRemessaAdicionar.EnderecoPagador =
            //    boletoAdicionar.SacadoBoleto.EnderecoSacado.LogradouroNumeroComplementoConcatenado;
            //detalheRemessaAdicionar.CidadePagador = boletoAdicionar.SacadoBoleto.EnderecoSacado.Cidade;
            //detalheRemessaAdicionar.UfPagador = boletoAdicionar.SacadoBoleto.EnderecoSacado.SiglaUf;
            //detalheRemessaAdicionar.CepPagador = boletoAdicionar.SacadoBoleto.EnderecoSacado.Cep;
            //detalheRemessaAdicionar.NumeroSequencialRegistro = numeroSequencialRegistro;
        }
        public string EscreverDetalhe(DetalheRemessaCnab400 infoDetalhe)
        {
            if (infoDetalhe == null)
                throw new Exception("Não há boleto para geração do DETALHE");

            if (infoDetalhe.NumeroSequencialRegistro == 0)
                throw new Exception("Sequencial do registro não foi informado na geração do DETALHE.");

            string enderecoSacado = string.Empty;

            string nomeSacado = string.Empty;

            if (String.IsNullOrEmpty(infoDetalhe.EnderecoPagador))
                enderecoSacado.PadRight(40, ' ');
            else
                if (infoDetalhe.EnderecoPagador.Length > 40)
                    enderecoSacado = infoDetalhe.EnderecoPagador.Substring(0, 40).ToUpper();
                else
                    enderecoSacado = infoDetalhe.EnderecoPagador.PadRight(40, ' ').ToUpper();

            if (String.IsNullOrEmpty(infoDetalhe.NomePagador))
                nomeSacado.PadRight(40, ' ');
            else
                if (infoDetalhe.NomePagador.Length > 40)
                    nomeSacado = infoDetalhe.NomePagador.Substring(0, 40).ToUpper();
                else
                    nomeSacado = infoDetalhe.NomePagador.PadRight(40, ' ').ToUpper();

            var detalhe = new string(' ', 400);
            try
            {
                detalhe = detalhe.PreencherValorNaLinha(1, 1, "1");
                // Débito Autómático em C/C
                detalhe = detalhe.PreencherValorNaLinha(2, 6, string.Empty.PadLeft(5, '0'));
                detalhe = detalhe.PreencherValorNaLinha(7, 7, "0");
                detalhe = detalhe.PreencherValorNaLinha(8, 12, string.Empty.PadLeft(5, '0'));
                detalhe = detalhe.PreencherValorNaLinha(13, 19, string.Empty.PadLeft(7, '0'));
                detalhe = detalhe.PreencherValorNaLinha(20, 20, "0");

                #region POSIÇÃO: 21-37 - IDENTIFICAÇÃO DA EMPRESA CEDENTE NO BANCO

                detalhe = detalhe.PreencherValorNaLinha(21, 37, infoDetalhe.CodigoCedente.PadLeft(17, '0'));

                #endregion

                const string doc = "DOC";
                var seuNumero = doc + infoDetalhe.NossoNumeroFormatado.PadRight(25 - doc.Length, ' ');

                detalhe = detalhe.PreencherValorNaLinha(38, 62, seuNumero);
                detalhe = detalhe.PreencherValorNaLinha(63, 65, "237");
                detalhe = detalhe.PreencherValorNaLinha(66, 66, "0"); // Sem cobrança de multa
                detalhe = detalhe.PreencherValorNaLinha(67, 70, "0000"); // Percentual de multa
                detalhe = detalhe.PreencherValorNaLinha(71, 81, infoDetalhe.NossoNumero.PadLeft(11, '0'));
                detalhe = detalhe.PreencherValorNaLinha(82, 82, infoDetalhe.DvNossoNumero);

                #region VALOR DESCONTO POR DIA

                var valorDescontoDia = string.Empty;

                if (infoDetalhe.ValorDescontoDia.ToString().Contains('.') && infoDetalhe.ValorDescontoDia.ToString().Contains(','))
                {
                    valorDescontoDia = infoDetalhe.ValorDescontoDia.ToString().Replace(".", "").Replace(",", "");
                    detalhe = detalhe.PreencherValorNaLinha(83, 92, valorDescontoDia.PadLeft(10, '0'));
                }
                if (infoDetalhe.ValorDesconto.ToString().Contains('.'))
                {
                    valorDescontoDia = infoDetalhe.ValorDescontoDia.ToString().Replace(".", "");
                    detalhe = detalhe.PreencherValorNaLinha(83, 92, valorDescontoDia.PadLeft(10, '0'));
                }
                if (infoDetalhe.ValorDesconto.ToString().Contains(','))
                {
                    valorDescontoDia = infoDetalhe.ValorDescontoDia.ToString().Replace(",", "");
                    detalhe = detalhe.PreencherValorNaLinha(83, 92, valorDescontoDia.PadLeft(10, '0'));
                }

                detalhe = detalhe.PreencherValorNaLinha(83, 92, valorDescontoDia.PadLeft(10, '0'));

                #endregion

                detalhe = detalhe.PreencherValorNaLinha(93, 93, "2");
                detalhe = detalhe.PreencherValorNaLinha(94, 94, "N");
                detalhe = detalhe.PreencherValorNaLinha(95, 104, string.Empty.PadLeft(10, ' '));
                detalhe = detalhe.PreencherValorNaLinha(105, 105, " ");
                detalhe = detalhe.PreencherValorNaLinha(106, 106, "2");
                detalhe = detalhe.PreencherValorNaLinha(107, 108, string.Empty.PadLeft(2, ' '));
                detalhe = detalhe.PreencherValorNaLinha(109, 110, "01");
                detalhe = detalhe.PreencherValorNaLinha(111, 120, infoDetalhe.NumeroDocumento.PadLeft(10, '0'));
                detalhe = detalhe.PreencherValorNaLinha(121, 126, infoDetalhe.DataVencimento.ToString("ddMMyy"));

                #region VALOR BOLETO

                detalhe = detalhe.PreencherValorNaLinha(127, 139,
                    infoDetalhe.ValorBoleto.ToString("f").Replace(".", "").Replace(",", "").PadLeft(13, '0'));

                #endregion

                //if (infoDetalhe.CodigoOcorrencia.Codigo.Equals(01))
                //{
                //    detalhe = detalhe.PreencherValorNaLinha(140, 142, string.Empty.PadLeft(3, '0'));
                //    detalhe = detalhe.PreencherValorNaLinha(143, 147, string.Empty.PadLeft(5, '0'));
                //}
                //else
                //{
                //    detalhe = detalhe.PreencherValorNaLinha(140, 142, infoDetalhe.CodigoBanco.PadLeft(3, '0'));
                //    detalhe = detalhe.PreencherValorNaLinha(143, 147, infoDetalhe.Agencia.PadLeft(4, '0') + infoDetalhe.DvAgencia);
                //}

                detalhe = detalhe.PreencherValorNaLinha(140, 142, string.Empty.PadLeft(3, '0'));
                detalhe = detalhe.PreencherValorNaLinha(143, 147, string.Empty.PadLeft(5, '0'));

                detalhe = detalhe.PreencherValorNaLinha(148, 149,
                    infoDetalhe.Especie.Sigla.Equals("DM")
                        ? "01"
                        : infoDetalhe.Especie.Codigo.ToString());
                detalhe = detalhe.PreencherValorNaLinha(150, 150, infoDetalhe.Aceite.Equals("A") ? "A" : "N");
                detalhe = detalhe.PreencherValorNaLinha(151, 156, infoDetalhe.DataEmissao.ToString("ddMMyy"));

                #region INSTRUÇÕES REMESSA

                var primeiraInstrucao = infoDetalhe.Instrucao1;
                var segundaInstrucao = infoDetalhe.Instrucao2;

                if (primeiraInstrucao != null)
                    detalhe = detalhe.PreencherValorNaLinha(157, 158, primeiraInstrucao);
                else
                    detalhe = detalhe.PreencherValorNaLinha(157, 158, "00");
                if (segundaInstrucao != null)
                    detalhe = detalhe.PreencherValorNaLinha(159, 160, segundaInstrucao);
                else
                    detalhe = detalhe.PreencherValorNaLinha(159, 160, "00");

                #endregion

                #region VALOR JUROS

                var jurosBoleto = string.Empty;

                if (infoDetalhe.ValorCobradoDiaAtraso.ToString().Contains('.') && infoDetalhe.ValorCobradoDiaAtraso.ToString().Contains(','))
                {
                    jurosBoleto = infoDetalhe.ValorCobradoDiaAtraso.ToString().Replace(".", "").Replace(",", "");
                    detalhe = detalhe.PreencherValorNaLinha(161, 173, jurosBoleto.PadLeft(13, '0'));
                }
                if (infoDetalhe.ValorCobradoDiaAtraso.ToString().Contains('.'))
                {
                    jurosBoleto = infoDetalhe.ValorCobradoDiaAtraso.ToString().Replace(".", "");
                    detalhe = detalhe.PreencherValorNaLinha(161, 173, jurosBoleto.PadLeft(13, '0'));
                }
                if (infoDetalhe.ValorCobradoDiaAtraso.ToString().Contains(','))
                {
                    jurosBoleto = infoDetalhe.ValorCobradoDiaAtraso.ToString().Replace(",", "");
                    detalhe = detalhe.PreencherValorNaLinha(161, 173, jurosBoleto.PadLeft(13, '0'));
                }

                detalhe = detalhe.PreencherValorNaLinha(161, 173, jurosBoleto.PadLeft(13, '0'));
                    // Valor de Mora Por Dia de Atraso

                #endregion

                if (infoDetalhe.DataLimiteConcessaoDesconto == DateTime.MinValue)
                    detalhe = detalhe.PreencherValorNaLinha(174, 179, string.Empty.PadLeft(6, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(174, 179, infoDetalhe.DataLimiteConcessaoDesconto.ToString("ddMMyy"));
                        // Data Limite para Concesão de Desconto

                #region VALOR DESCONTO

                detalhe = detalhe.PreencherValorNaLinha(180, 192, infoDetalhe.ValorDesconto.ToString("f").Replace(".", "").Replace(",", "").PadLeft(13, '0'));

                #endregion

                #region VALOR IOF

                string iofBoleto;

                if (infoDetalhe.ValorIof.ToString().Contains('.') && infoDetalhe.ValorIof.ToString().Contains(','))
                {
                    iofBoleto = infoDetalhe.ValorIof.ToString().Replace(".", "").Replace(",", "");
                    detalhe = detalhe.PreencherValorNaLinha(193, 205, iofBoleto.PadLeft(13, '0'));
                }
                if (infoDetalhe.ValorIof.ToString().Contains('.'))
                {
                    iofBoleto = infoDetalhe.ValorIof.ToString().Replace(".", "");
                    detalhe = detalhe.PreencherValorNaLinha(193, 205, iofBoleto.PadLeft(13, '0'));
                }
                if (infoDetalhe.ValorIof.ToString().Contains(','))
                {
                    iofBoleto = infoDetalhe.ValorIof.ToString().Replace(",", "");
                    detalhe = detalhe.PreencherValorNaLinha(193, 205, iofBoleto.PadLeft(13, '0'));
                }

                detalhe = detalhe.PreencherValorNaLinha(193, 205, infoDetalhe.ValorIof.ToString().PadLeft(13, '0'));
                    // Valor do I.O.F. recolhido p/ notas seguro

                #endregion

                #region VALOR ABATIMENTO

                string abatimentoBoleto;

                if (infoDetalhe.ValorAbatimento.ToString().Contains('.') && infoDetalhe.ValorAbatimento.ToString().Contains(','))
                {
                    abatimentoBoleto = infoDetalhe.ValorAbatimento.ToString().Replace(".", "").Replace(",", "");
                    detalhe = detalhe.PreencherValorNaLinha(206, 218, abatimentoBoleto.PadLeft(13, '0'));
                }
                if (infoDetalhe.ValorAbatimento.ToString().Contains('.'))
                {
                    abatimentoBoleto = infoDetalhe.ValorAbatimento.ToString().Replace(".", "");
                    detalhe = detalhe.PreencherValorNaLinha(206, 218, abatimentoBoleto.PadLeft(13, '0'));
                }
                if (infoDetalhe.ValorAbatimento.ToString().Contains(','))
                {
                    abatimentoBoleto = infoDetalhe.ValorAbatimento.ToString().Replace(",", "");
                    detalhe = detalhe.PreencherValorNaLinha(206, 218, abatimentoBoleto.PadLeft(13, '0'));
                }

                detalhe = detalhe.PreencherValorNaLinha(206, 218, infoDetalhe.ValorAbatimento.ToString().PadLeft(13, '0'));

                #endregion

                detalhe = detalhe.PreencherValorNaLinha(219, 220,
                    infoDetalhe.InscricaoPagador.Replace(".", "").Replace("/", "").Replace("-", "").Length == 11 ? "01" : "02"); // Identificação do tipo de inscrição/sacado
                detalhe = detalhe.PreencherValorNaLinha(221, 234, infoDetalhe.InscricaoPagador.Replace(".", "").Replace("/", "").Replace("-", "").PadLeft(14, '0'));
                detalhe = detalhe.PreencherValorNaLinha(235, 274, nomeSacado);
                detalhe = detalhe.PreencherValorNaLinha(275, 314, enderecoSacado);

                #region 1ª Mensagem

                /* POSIÇÃO: 315 a 326 - 1ª Mensagem
                 * Campo livre para uso da empresa.
                 * A mensagem enviada nesse campo será impressa somente no boleto enão será confirmada no arquivo retorno.
                 */
                detalhe = detalhe.PreencherValorNaLinha(315, 326, string.Empty.PadLeft(12, ' ')); // 1ª Mensagem

                #endregion

                var cep = infoDetalhe.CepPagador;

                if (cep.Contains(".") && cep.Contains("-"))
                    cep = cep.Replace(".", "").Replace("-", "");
                if (cep.Contains("."))
                    cep = cep.Replace(".", "");
                if (cep.Contains("-"))
                    cep = cep.Replace("-", "");

                detalhe = detalhe.PreencherValorNaLinha(327, 334, cep.PadLeft(8, ' ')); // Cep do Sacado

                #region 2ª Mensagem / Sacador Avalista

                /* Sacador / Avalista ou 2ª Mensagem
                 * CNPJ/CPF do Sacador Avalista ( o critério para preenchimento, deve ser o mesmo tanto para o
                 * CNPJ como para o CPF ou seja, iniciando da direita para a esquerda:
                 * - 2 posições para o controle;
                 * - 4 posições para filial; e
                 * - 9 posições para o CNPJ/CPF.
                 * Obs.: No caso de CPF, o campo filial deverá ser preenchido com zeros.
                 * COMPOSIÇÃO DAS POSIÇÕES 335-394
                 * 15 Numéricos
                 * 02 Brancos
                 * 43 Alfanumérico
                 */

                string str = string.Empty;

                if (String.IsNullOrEmpty(infoDetalhe.NomeAvalistaOuMensagem2))
                    detalhe = detalhe.PreencherValorNaLinha(335, 394, str.PadLeft(60, ' '));
                //else
                //{
                //    if (boleto.SacadoBoleto.CpfCnpjAvalista.Replace(".", "").Replace("/", "").Replace("-", "").Length ==
                //        11)
                //    {
                //        str = (boleto.SacadoBoleto.NomeAvalista.ToUpper() +
                //               string.Empty.PadLeft(2, ' ') +
                //               boleto.SacadoBoleto.CpfCnpjAvalista.Replace(".", "")
                //                   .Replace("/", "")
                //                   .Replace("-", "")
                //                   .Substring(0, 9) +
                //               string.Empty.PadLeft(4, '0') +
                //               boleto.SacadoBoleto.CpfCnpjAvalista.Replace(".", "")
                //                   .Replace("/", "")
                //                   .Replace("-", "")
                //                   .Substring(9, 2));
                //    }
                //    else
                //    {
                //        str = (boleto.SacadoBoleto.NomeAvalista.ToUpper() +
                //               string.Empty.PadLeft(2, ' ') +
                //               boleto.SacadoBoleto.CpfCnpjAvalista.Replace(".", "")
                //                   .Replace("/", "")
                //                   .Replace("-", "")
                //                   .PadLeft(15, '0'));
                //    }

                //    detalhe = detalhe.PreencherValorNaLinha(335, 394, str.PadLeft(60, ' '));
                //}

                #endregion

                detalhe = detalhe.PreencherValorNaLinha(395, 400, infoDetalhe.NumeroSequencialRegistro.ToString().PadLeft(6, '0'));

                return detalhe;
            }
            catch (Exception e)
            {
                throw new Exception(string.Format("<BoletoBr>{0}Falha na geração do DETALHE do arquivo de REMESSA.",
                    Environment.NewLine), e);
            }
        }
        public string EscreverDetalhe(DetalheRemessaCnab400 infoDetalhe)
        {
            if (String.IsNullOrEmpty(infoDetalhe.BairroPagador))
                throw new Exception("Não foi informado o bairro do pagador " + infoDetalhe.NomePagador + "(" +
                                    infoDetalhe.InscricaoPagador + ")");

            if (String.IsNullOrEmpty(infoDetalhe.CepPagador) || infoDetalhe.CepPagador.Length < 8)
                throw new Exception("CEP Inválida! Verifique o CEP do pagador " + infoDetalhe.NomePagador + "(" +
                                    infoDetalhe.InscricaoPagador + ")");

            // Na geração do detalhe na remessa não está sendo tratado os casos de cancelamento das instruções nas posições 34-37

            #region Variáveis

            var objBanco = BancoFactory.ObterBanco(infoDetalhe.CodigoBanco);

            //string nossoNumeroCarteira =
            //    infoDetalhe.NossoNumeroFormatado.Replace(".", "").Replace("/", "").Replace("-", "").Substring(0, 3);
            string nossoNumeroSequencial =
                infoDetalhe.NossoNumeroFormatado.Replace(".", "").Replace("/", "").Replace("-", "").Substring(3, 8);
            //string nossoNumeroDigito =
            //    infoDetalhe.NossoNumeroFormatado.Replace(".", "").Replace("/", "").Replace("-", "").Substring(11, 1);

            string carteiraCob = infoDetalhe.CarteiraCobranca.PadLeft(3, ' ');
            string enderecoSacado = string.Empty;
            string bairroSacado = string.Empty;
            string cidadeSacado = string.Empty;

            string nomeSacado = string.Empty;

            #endregion

            if (String.IsNullOrEmpty(infoDetalhe.EnderecoPagador))
                enderecoSacado.PadRight(40, ' ');
            else if (infoDetalhe.EnderecoPagador.Length > 40)
                enderecoSacado = infoDetalhe.EnderecoPagador.Substring(0, 40).ToUpper();
            else
                enderecoSacado = infoDetalhe.EnderecoPagador.PadRight(40, ' ').ToUpper();

            if (String.IsNullOrEmpty(infoDetalhe.BairroPagador))
                bairroSacado.PadRight(12, ' ');
            else if (infoDetalhe.BairroPagador.Length > 12)
                bairroSacado = infoDetalhe.BairroPagador.Substring(0, 12).ToUpper();
            else
                bairroSacado = infoDetalhe.BairroPagador.PadRight(12, ' ').ToUpper();

            if (String.IsNullOrEmpty(infoDetalhe.CidadePagador))
                cidadeSacado.PadRight(15, ' ');
            else if (infoDetalhe.CidadePagador.Length > 15)
                cidadeSacado = infoDetalhe.CidadePagador.Substring(0, 15).ToUpper();
            else
                cidadeSacado = infoDetalhe.CidadePagador.PadRight(15, ' ').ToUpper();

            if (String.IsNullOrEmpty(infoDetalhe.NomePagador))
                nomeSacado.PadRight(30, ' ');
            else if (infoDetalhe.NomePagador.Length > 30)
                nomeSacado = infoDetalhe.NomePagador.Substring(0, 30).ToUpper();
            else
                nomeSacado = infoDetalhe.NomePagador.PadRight(30, ' ').ToUpper();

            var detalhe = new string(' ', 400);
            try
            {
                detalhe = detalhe.PreencherValorNaLinha(1, 1, "1"); // Identificação do Registro Transação
                detalhe = detalhe.PreencherValorNaLinha(2, 3,
                    infoDetalhe.InscricaoCedente.Replace(".", "").Replace("/", "").Replace("-", "").Length == 11
                        ? "01"
                        : "02"); // Tipo de Inscrição da Empresa
                detalhe = detalhe.PreencherValorNaLinha(4, 17,
                    infoDetalhe.InscricaoCedente.Replace(".", "").Replace("/", "").Replace("-", ""));
                // Nro de Inscrição da Empresa (CPF/CNPJ)
                detalhe = detalhe.PreencherValorNaLinha(18, 21, infoDetalhe.Agencia.PadLeft(4, '0'));
                    // Agência Mantenedora da Conta
                detalhe = detalhe.PreencherValorNaLinha(22, 23, string.Empty.PadRight(2, '0'));
                // Complemento de Registro
                detalhe = detalhe.PreencherValorNaLinha(24, 28, infoDetalhe.ContaCorrente.PadLeft(5, '0'));
                // Nro da Conta Corrente da Empresa
                detalhe = detalhe.PreencherValorNaLinha(29, 29, infoDetalhe.DvContaCorrente);
                // Dígito de Auto Conferência Ag/Conta Empresa
                detalhe = detalhe.PreencherValorNaLinha(30, 33, string.Empty.PadRight(4, ' '));
                // Complemento de Registro

                if (infoDetalhe.CodigoOcorrencia.Codigo != 35 && infoDetalhe.CodigoOcorrencia.Codigo != 38)
                    detalhe = detalhe.PreencherValorNaLinha(34, 37, "0000"); // Cód. Instrução/Alegação a ser cancelada

                const string doc = "DOC";
                var seuNumero = doc + infoDetalhe.NossoNumeroFormatado.PadRight(25 - doc.Length, ' ');

                detalhe = detalhe.PreencherValorNaLinha(38, 62, seuNumero); // Identificação do Título na Empresa
                detalhe = detalhe.PreencherValorNaLinha(63, 70, nossoNumeroSequencial);
                // Identificação do Título no Banco

                // Se Moeda = REAL, preenche com zeros
                if (infoDetalhe.Moeda == "9" || infoDetalhe.Moeda == "09" || infoDetalhe.Moeda == "R$" ||
                    infoDetalhe.Moeda == "REAL")
                    detalhe = detalhe.PreencherValorNaLinha(71, 83, string.Empty.PadLeft(13, '0'));
                    // Quantidade de Moeda Variável
                    // Caso contrário, preenche com a quantidade
                else
                    detalhe = detalhe.PreencherValorNaLinha(71, 83,
                        infoDetalhe.QuantidadeMoeda.ToString("F5").Replace(".", "").Replace(",", "").PadLeft(13, '0'));
                        // Quantidade de Moeda Variável
                detalhe = detalhe.PreencherValorNaLinha(84, 86, infoDetalhe.CarteiraCobranca.PadLeft(3, '0'));
                // Número da Carteira no Banco
                detalhe = detalhe.PreencherValorNaLinha(87, 107, string.Empty.PadRight(21, ' '));
                // Identificação da Operação no Banco
                /* Código da Carteira */
                // Modalidade de Carteira D - Direta
                if (carteiraCob == "108" || carteiraCob == "109" || carteiraCob == "110" || carteiraCob == "111")
                    detalhe = detalhe.PreencherValorNaLinha(108, 108, "I");
                // Modalidade de Carteira S - Sem Registro
                if (carteiraCob == "103" || carteiraCob == "173" || carteiraCob == "196" || carteiraCob == "198")
                    detalhe = detalhe.PreencherValorNaLinha(108, 108, "I");
                // Modalidade de Carteira E - Escritural
                if (carteiraCob == "104" || carteiraCob == "112" || carteiraCob == "138")
                    detalhe = detalhe.PreencherValorNaLinha(108, 108, "I");
                if (carteiraCob == "147")
                    detalhe = detalhe.PreencherValorNaLinha(108, 108, "E");
                detalhe = detalhe.PreencherValorNaLinha(109, 110,
                    infoDetalhe.CodigoOcorrencia.Codigo.ToString().PadLeft(2, '0')); // Identificação da Ocorrência
                detalhe = detalhe.PreencherValorNaLinha(111, 120, infoDetalhe.NumeroDocumento.Replace("-", ""));
                detalhe = detalhe.PreencherValorNaLinha(121, 126, infoDetalhe.DataVencimento.ToString("ddMMyy"));
                // Data de Vencimento do Título
                detalhe = detalhe.PreencherValorNaLinha(127, 139,
                    infoDetalhe.ValorBoleto.ToString("f").Replace(".", "").Replace(",", "").PadLeft(13, '0'));
                // Valor Nominal do Título
                detalhe = detalhe.PreencherValorNaLinha(140, 142, "341"); // Nro do Banco na Câmara de Compensação
                detalhe = detalhe.PreencherValorNaLinha(143, 147, string.Empty.PadLeft(5, '0'));
                // Agência onde o título será cobrado
                // Espécie do documento padronizado para DM - Duplicata Mercantil
                detalhe = detalhe.PreencherValorNaLinha(148, 149,
                    infoDetalhe.Especie.Sigla.Equals("DM") ? "01" : infoDetalhe.Especie.Codigo.ToString());
                if (String.IsNullOrEmpty(infoDetalhe.Aceite))
                    detalhe = detalhe.PreencherValorNaLinha(150, 150, "N");
                else
                    detalhe = detalhe.PreencherValorNaLinha(150, 150, infoDetalhe.Aceite.Equals("A") ? "A" : "N");
                // Identificação de Título Aceitou ou Não Aceito
                detalhe = detalhe.PreencherValorNaLinha(151, 156, infoDetalhe.DataEmissao.ToString("ddMMyy"));
                // Data da Emissão do Título

                #region INSTRUÇÕES REMESSA

                if (infoDetalhe.Instrucoes.Count > 2)
                    throw new Exception(
                        string.Format(
                            "<BoletoBr>{0}Não são aceitas mais que 2 instruções padronizadas para remessa de boletos no banco Itaú.",
                            Environment.NewLine));

                var primeiraInstrucao = infoDetalhe.Instrucoes.FirstOrDefault();
                var segundaInstrucao = infoDetalhe.Instrucoes.LastOrDefault();

                // No caso da instrução "39", se informar "00" na posição 392-393 será impresso no boleto a literal "NÃO RECEBER APÓS O VENCIMENTO".
                if (primeiraInstrucao != null && primeiraInstrucao.Codigo.BoletoBrToStringSafe().Length == 2)
                    detalhe = detalhe.PreencherValorNaLinha(157, 158, primeiraInstrucao.Codigo.ToString());
                else
                    detalhe = detalhe.PreencherValorNaLinha(157, 158, "39");

                // Pagável em qualquer agência bancária até a data de vencimento Código 90.
                if (segundaInstrucao != null && segundaInstrucao.Codigo.BoletoBrToStringSafe().Length == 2)
                    detalhe = detalhe.PreencherValorNaLinha(159, 160, segundaInstrucao.Codigo.ToString());
                else
                    detalhe = detalhe.PreencherValorNaLinha(159, 160, "90");

                #endregion

                detalhe = detalhe.PreencherValorNaLinha(161, 173,
                    infoDetalhe.ValorMoraDia.ToString("f").Replace(",", "").PadLeft(13, '0'));
                // Valor de Mora Por Dia de Atraso

                if (infoDetalhe.DataDesconto == DateTime.MinValue)
                    detalhe = detalhe.PreencherValorNaLinha(174, 179, string.Empty.PadLeft(6, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(174, 179, infoDetalhe.DataDesconto.ToString("ddMMyy"));
                // Data Limite para Concesão de Desconto

                detalhe = detalhe.PreencherValorNaLinha(180, 192,
                    infoDetalhe.ValorDesconto.ToString().Replace(",", "").PadLeft(13, '0'));
                // Valor do Desconto a ser Concedido
                detalhe = detalhe.PreencherValorNaLinha(193, 205,
                    infoDetalhe.ValorIof.ToString().Replace(",", "").PadLeft(13, '0'));
                // Valor do I.O.F. recolhido p/ notas seguro
                detalhe = detalhe.PreencherValorNaLinha(206, 218,
                    infoDetalhe.ValorAbatimento.ToString().Replace(",", "").PadLeft(13, '0'));
                // Valor do Abatimento a ser concedido
                detalhe = detalhe.PreencherValorNaLinha(219, 220,
                    infoDetalhe.InscricaoPagador.Replace(".", "").Replace("/", "").Replace("-", "").Length == 11
                        ? "01"
                        : "02"); // Identificação do tipo de inscrição/sacado
                detalhe = detalhe.PreencherValorNaLinha(221, 234,
                    infoDetalhe.InscricaoPagador.Replace(".", "").Replace("/", "").Replace("-", "").PadLeft(14, '0'));
                // Nro de Inscrição do Sacado (CPF/CNPJ)
                detalhe = detalhe.PreencherValorNaLinha(235, 264, nomeSacado.PadRight(30, ' ')); // Nome do Sacado
                detalhe = detalhe.PreencherValorNaLinha(265, 274, string.Empty.PadRight(10, ' '));
                    // Complemento de registro
                detalhe = detalhe.PreencherValorNaLinha(275, 314, enderecoSacado.PadRight(40, ' '));
                // Rua, Número, e Complemento do Sacado
                detalhe = detalhe.PreencherValorNaLinha(315, 326, bairroSacado.PadRight(12, ' ')); // Bairro do Sacado

                var Cep = infoDetalhe.CepPagador;

                if (Cep.Contains("."))
                    Cep = Cep.Replace(".", "");
                if (Cep.Contains("-"))
                    Cep = Cep.Replace("-", "");

                detalhe = detalhe.PreencherValorNaLinha(327, 334, Cep);
                detalhe = detalhe.PreencherValorNaLinha(335, 349, cidadeSacado.PadRight(15, ' '));
                detalhe = detalhe.PreencherValorNaLinha(350, 351, infoDetalhe.UfPagador.PadRight(2, ' '));

                if (String.IsNullOrEmpty(infoDetalhe.NomeAvalistaOuMensagem2))
                    detalhe = detalhe.PreencherValorNaLinha(352, 381, string.Empty.PadRight(30, ' '));
                    // Nome do Sacador ou Avalista
                else
                    detalhe = detalhe.PreencherValorNaLinha(352, 381,
                        infoDetalhe.NomeAvalistaOuMensagem2.PadRight(30, ' '));
                // Nome do Sacador ou Avalista

                detalhe = detalhe.PreencherValorNaLinha(382, 385, string.Empty.PadRight(4, ' '));
                // Complemento do Registro

                if (infoDetalhe.DataJurosMora == DateTime.MinValue)
                    detalhe = detalhe.PreencherValorNaLinha(386, 391, string.Empty.PadLeft(6, '0')); // Data de Mora
                else
                    detalhe = detalhe.PreencherValorNaLinha(386, 391, infoDetalhe.DataJurosMora.ToString("ddMMyy"));
                // Data de Mora
                detalhe = detalhe.PreencherValorNaLinha(392, 393,
                    infoDetalhe.NroDiasParaProtesto.ToString().PadLeft(2, '0'));
                // Quantidade de Dias Posição 392 a 393
                detalhe = detalhe.PreencherValorNaLinha(394, 394, string.Empty.PadRight(1, ' '));
                // Complemento do Registro
                detalhe = detalhe.PreencherValorNaLinha(395, 400,
                    infoDetalhe.NumeroSequencialRegistro.ToString().PadLeft(6, '0'));
                // Nro Sequencial do Registro no Arquivo

                return detalhe;
            }
            catch (Exception e)
            {
                throw new Exception(string.Format("<BoletoBr>{0}Falha na geração do DETALHE do arquivo de REMESSA.",
                    Environment.NewLine), e);
            }
        }
        public void TestGeracaoArquivoRemessa()
        {
            var dadosRemessa = new Remessa(Remessa.EnumTipoAmbiemte.Homologacao, EnumCodigoOcorrenciaRemessa.Registro, "2");

            var banco = Fabricas.BancoFactory.ObterBanco("237", "2");

            var contaBancariaCedente = new ContaBancaria("1234", "8", "12345", "6");

            var cedente = new Cedente("99999", "1", 0, "99.999.999/9999-99", "Razao Social X", contaBancariaCedente, null);

            var sacado = new Sacado("Sacado Fulano de Tal", "99.999.999/9999-99", new Endereco()
            {
                TipoLogradouro = "R",
                Logradouro = "1",
                Bairro = "Bairro X",
                Cidade = "Cidade X",
                SiglaUf = "XX",
                Cep = "12345-000",
                Complemento = "Comp X",
                Numero = "9"
            });

            var carteira = new CarteiraCobranca { Codigo = "06" };

            var boleto = new Boleto(carteira, cedente, sacado, dadosRemessa)
            {
                NumeroDocumento = "3242",
                ValorBoleto = Convert.ToDecimal(275),
                IdentificadorInternoBoleto = "3242",
                DataVencimento = new DateTime(2014, 08, 04),
                Especie = banco.ObtemEspecieDocumento(EnumEspecieDocumento.DuplicataMercantil)
            };

            banco.FormatarBoleto(boleto);

            var remessa = new RemessaCnab400();

            remessa.Header = new HeaderRemessaCnab400(boleto, 1, 1);

            var detalheIndividual = new DetalheRemessaCnab400(boleto, 1);

            remessa.RegistrosDetalhe = new List<DetalheRemessaCnab400>
            {
                detalheIndividual
            };

            remessa.Trailer = new TrailerRemessaCnab400(1, 1);

            var escritor = new EscritorRemessaCnab400Bradesco(remessa);

            var linhasEscrever = escritor.EscreverTexto(remessa);

            var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

            var data = String.Format("{0}_{1}", DateTime.Now.ToString("ddMMyyyy"), DateTime.Now.ToString("HHmmss"));

            var nomeArquivo = string.Format("{0}{1}{2}{3}", banco.CodigoBanco, @"_REMESSA_", data, ".txt");

            StringBuilder sb = new StringBuilder();
            foreach (var linha in linhasEscrever)
            {
                sb.AppendLine(linha);
            }

            File.WriteAllLines(path, linhasEscrever.ToArray());
        }
        public string EscreverDetalhe(DetalheRemessaCnab400 infoDetalhe)
        {
            if (infoDetalhe.TipoCarteiraCobranca != "1" &&
                infoDetalhe.TipoCarteiraCobranca != "2" &&
                infoDetalhe.TipoCarteiraCobranca != "3")
                throw new Exception(
                    "Informe o tipo carteira de cobrança. 1- Sem Registro; 2- Com Registro- Impressão Local ou 3- Com Registro- Impressão pelo BRB");

            #region Variáveis

            var objBanco = BancoFactory.ObterBanco(infoDetalhe.CodigoBanco);

            var enderecoSacado = string.Empty;
            var cidadeSacado = string.Empty;
            var nomeSacado = string.Empty;
            var tipoSacado = string.Empty;

            #endregion

            if (String.IsNullOrEmpty(infoDetalhe.EnderecoPagador))
                enderecoSacado.PadRight(35, ' ');
            else
            {
                enderecoSacado = infoDetalhe.EnderecoPagador.Length > 35
                    ? infoDetalhe.EnderecoPagador.ExtrairValorDaLinha(0, 35).ToUpper()
                    : infoDetalhe.EnderecoPagador.PadRight(35, ' ').ToUpper();
            }

            if (String.IsNullOrEmpty(infoDetalhe.CidadePagador))
                cidadeSacado.PadRight(15, ' ');
            else
            {
                cidadeSacado = infoDetalhe.CidadePagador.Length > 15
                    ? infoDetalhe.CidadePagador.ExtrairValorDaLinha(0, 15).ToUpper()
                    : infoDetalhe.CidadePagador.PadRight(15, ' ').ToUpper();
            }

            if (String.IsNullOrEmpty(infoDetalhe.NomePagador))
                nomeSacado.PadRight(35, ' ');
            else
            {
                nomeSacado = infoDetalhe.NomePagador.Length > 35
                    ? infoDetalhe.NomePagador.ExtrairValorDaLinha(0, 35).ToUpper()
                    : infoDetalhe.NomePagador.PadRight(35, ' ').ToUpper();
            }

            //1- Física; 2- Jurídica ou 9- Isenta
            switch (infoDetalhe.InscricaoPagador.Replace(".", "").Replace("/", "").Replace("-", "").Length)
            {
                case 11:
                    tipoSacado = "1";
                    break;
                case 14:
                    tipoSacado = "2";
                    break;
                default:
                    tipoSacado = "9";
                    break;
            }

            var detalhe = new string(' ', 400);
            try
            {
                detalhe = detalhe.PreencherValorNaLinha(1, 2, "01"); // Identificação do Registro Transação
                detalhe = detalhe.PreencherValorNaLinha(3, 5, infoDetalhe.Agencia);
                detalhe = detalhe.PreencherValorNaLinha(6, 12,
                    (infoDetalhe.ContaCorrente + infoDetalhe.DvContaCorrente).PadLeft(7, '0'));
                detalhe = detalhe.PreencherValorNaLinha(13, 26,
                    infoDetalhe.InscricaoPagador.Replace(".", "").Replace("/", "").Replace("-", "").PadRight(14, ' '));
                detalhe = detalhe.PreencherValorNaLinha(27, 61, nomeSacado);
                detalhe = detalhe.PreencherValorNaLinha(62, 96, enderecoSacado);
                detalhe = detalhe.PreencherValorNaLinha(97, 111, cidadeSacado);
                detalhe = detalhe.PreencherValorNaLinha(112, 113, infoDetalhe.UfPagador.PadRight(2, ' '));
                detalhe = detalhe.PreencherValorNaLinha(114, 121,
                    infoDetalhe.CepPagador.Replace(".", "").Replace("-", "").PadLeft(8, '0'));
                detalhe = detalhe.PreencherValorNaLinha(122, 122, tipoSacado);
                detalhe = detalhe.PreencherValorNaLinha(123, 135, infoDetalhe.NumeroDocumento.PadLeft(13, '0'));
                detalhe = detalhe.PreencherValorNaLinha(136, 136, infoDetalhe.TipoCarteiraCobranca);
                detalhe = detalhe.PreencherValorNaLinha(137, 144, infoDetalhe.DataEmissao.ToString("ddMMyyyy"));
                detalhe = detalhe.PreencherValorNaLinha(145, 146, infoDetalhe.Especie.Codigo.ToString());

                //0- Simples
                detalhe = detalhe.PreencherValorNaLinha(147, 147, "0");

                //0- No vencimento; 1- À Vista ou 2- Contra Apresentação
                detalhe = detalhe.PreencherValorNaLinha(148, 148, "0");

                //02- Real; 51- UFIR ou 91- UPDF
                detalhe = detalhe.PreencherValorNaLinha(149, 150, "02");

                detalhe = detalhe.PreencherValorNaLinha(151, 153, "070");
                detalhe = detalhe.PreencherValorNaLinha(154, 157, infoDetalhe.Agencia.PadLeft(4, '0'));
                //detalhe = detalhe.PreencherValorNaLinha(158, 187, " ");
                detalhe = detalhe.PreencherValorNaLinha(188, 195, infoDetalhe.DataVencimento.ToString("ddMMyyyy"));
                detalhe = detalhe.PreencherValorNaLinha(196, 209,
                    infoDetalhe.ValorBoleto.ToString("f").Replace(".", "").Replace(",", "").PadLeft(14, '0'));

                if (infoDetalhe.TipoCarteiraCobranca == "3")
                    detalhe = detalhe.PreencherValorNaLinha(210, 221, string.Empty.PadLeft(12, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(210, 221, infoDetalhe.NossoNumeroFormatado);

                //00- Sem Juros ('Não Cobrar Juros');
                //50-Diário ("Juro de mora ao dia de...") ou
                //51- Mensal ("Juro de mora ao mês de ...%")
                if (infoDetalhe.TipoCobrancaJuro == TipoCobrancaJuro.JurosDiario)
                    detalhe = detalhe.PreencherValorNaLinha(222, 223, "50");
                else if (infoDetalhe.TipoCobrancaJuro == TipoCobrancaJuro.JurosMensal)
                    detalhe = detalhe.PreencherValorNaLinha(222, 223, "51");
                else
                    detalhe = detalhe.PreencherValorNaLinha(222, 223, "00");

                detalhe = detalhe.PreencherValorNaLinha(224, 237,
                    infoDetalhe.ValorJuros.ToString("f").Replace(",", "").PadLeft(14, '0'));
                detalhe = detalhe.PreencherValorNaLinha(238, 251,
                    infoDetalhe.ValorAbatimento.ToString("f").Replace(",", "").PadLeft(14, '0'));

                if (infoDetalhe.ValorDescontoDia > 0)
                    detalhe = detalhe.PreencherValorNaLinha(252, 253, "52");
                else if (infoDetalhe.ValorDesconto > 0)
                    detalhe = detalhe.PreencherValorNaLinha(252, 253, "53");
                else
                    detalhe = detalhe.PreencherValorNaLinha(252, 253, "00");

                if (infoDetalhe.DataLimiteConcessaoDesconto == DateTime.MinValue)
                    detalhe = detalhe.PreencherValorNaLinha(254, 261, string.Empty.PadLeft(8, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(254, 261,
                        infoDetalhe.DataLimiteConcessaoDesconto.ToString("ddMMyyyy"));

                if (infoDetalhe.ValorDescontoDia > 0)
                    detalhe = detalhe.PreencherValorNaLinha(262, 275,
                        infoDetalhe.ValorDescontoDia.ToString("f").Replace(",", "").PadLeft(14, '0'));
                else if (infoDetalhe.ValorDesconto > 0)
                    detalhe = detalhe.PreencherValorNaLinha(262, 275,
                        infoDetalhe.ValorDesconto.ToString("f").Replace(",", "").PadLeft(14, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(262, 275, string.Empty.PadLeft(14, '0'));

                #region Instruções

                if (infoDetalhe.Instrucoes.Count > 2)
                    throw new Exception(
                        string.Format(
                            "<BoletoBr>{0}Não são aceitas mais que 2 instruções padronizadas para remessa de boletos no banco BRB.",
                            Environment.NewLine));

                var primeiraInstrucao = infoDetalhe.Instrucoes.FirstOrDefault();

                if (primeiraInstrucao != null)
                {
                    detalhe = detalhe.PreencherValorNaLinha(276, 277,
                        primeiraInstrucao.Codigo.BoletoBrToStringSafe());
                    detalhe = detalhe.PreencherValorNaLinha(278, 279,
                        primeiraInstrucao.QtdDias.BoletoBrToStringSafe());

                    detalhe = detalhe.PreencherValorNaLinha(284, 288,
                        primeiraInstrucao.Valor.ToString("f").Replace(",", "").PadLeft(5, '0'));
                }
                else
                {
                    detalhe = detalhe.PreencherValorNaLinha(276, 277, "00");
                    detalhe = detalhe.PreencherValorNaLinha(278, 279, "00");

                    detalhe = detalhe.PreencherValorNaLinha(284, 288, string.Empty.PadLeft(5, '0'));
                }

                if (infoDetalhe.Instrucoes.Count > 1)
                {
                    var segundaIntrucao = infoDetalhe.Instrucoes.LastOrDefault();
                    detalhe = detalhe.PreencherValorNaLinha(280, 281, segundaIntrucao.Codigo.BoletoBrToStringSafe());
                    detalhe = detalhe.PreencherValorNaLinha(282, 283, segundaIntrucao.QtdDias.BoletoBrToStringSafe());
                }
                else
                {
                    detalhe = detalhe.PreencherValorNaLinha(280, 281, "00");
                    detalhe = detalhe.PreencherValorNaLinha(282, 283, "00");
                }

                #endregion

                var razao = "";
                if (infoDetalhe.RazaoContaCorrente.Length > 40)
                    razao = infoDetalhe.RazaoContaCorrente.ExtrairValorDaLinha(1, 40);
                else razao = infoDetalhe.RazaoContaCorrente;
                detalhe = detalhe.PreencherValorNaLinha(289, 328, razao.PadRight(40, ' '));

                var obs = "";
                if (infoDetalhe.Mensagem1.BoletoBrToStringSafe().Length > 40)
                    obs = infoDetalhe.Mensagem1.ExtrairValorDaLinha(1, 40);
                else
                    obs = infoDetalhe.Mensagem1.BoletoBrToStringSafe();
                detalhe = detalhe.PreencherValorNaLinha(329, 368, obs.PadRight(40, ' '));

                return detalhe;
            }
            catch (Exception e)
            {
                throw new Exception(string.Format("<BoletoBr>{0}Falha na geração do DETALHE do arquivo de REMESSA.",
                    Environment.NewLine), e);
            }
        }
        public void TestGerarDetalheArquivoRemessaBancoBrasilCnab400()
        {
            var remessa = new Remessa(Remessa.EnumTipoAmbiemte.Homologacao, EnumCodigoOcorrenciaRemessa.Registro, "2");

            var banco = Fabricas.BancoFactory.ObterBanco("001", "9");

            var contaBancariaCedente = new ContaBancaria("2374", "4", "0165199", "4");

            var cedente = new Cedente("9999999", "000123", 0, "99.999.999/9999-99", "Razão Social X", contaBancariaCedente, null);

            var sacado = new Sacado("Sacado Fulano de Tal", "999.999.999-99", new Endereco()
            {
                TipoLogradouro = "R",
                Logradouro = "1",
                Bairro = "Bairro X",
                Cidade = "Cidade X",
                SiglaUf = "XX",
                Cep = "12345-000",
                Complemento = "Comp X",
                Numero = "9"
            });

            var carteira = new CarteiraCobranca { Codigo = "16" };

            var boleto = new Boleto(carteira, cedente, sacado, remessa)
            {
                NumeroDocumento = "1",
                ValorBoleto = Convert.ToDecimal(221.40),
                IdentificadorInternoBoleto = "1",
                DataVencimento = new DateTime(2014, 07, 10),
                Especie = banco.ObtemEspecieDocumento(EnumEspecieDocumento.DuplicataMercantil),
                TipoModalidade = "21",
                CodigoOcorrenciaRemessa = new CodigoOcorrencia(01),
                BancoBoleto = banco
            };

            banco.FormatarBoleto(boleto);

            var remessaEscrever = new RemessaCnab400();

            remessaEscrever.Header = new HeaderRemessaCnab400(boleto, 1, 1, DateTime.Now);
            var detalheIndividual = new DetalheRemessaCnab400(boleto, 1);
            remessaEscrever.RegistrosDetalhe = new List<DetalheRemessaCnab400>
            {
                detalheIndividual
            };
            var escritor = new EscritorRemessaCnab400BancoDoBrasil(remessaEscrever);

            var linhasEscrever = escritor.EscreverTexto(remessaEscrever);

            //const int numeroRegistro = 1;

            //var escritor = new EscritorRemessaCnab400BancoDoBrasil();

            //var linhasEscrever = escritor.EscreverDetalhe(boleto, numeroRegistro);

            //var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

            //var data = DateTime.Now.ToString("ddMMyyyy");

            //var nomeArquivo = string.Format("{0}{1}{2}{3}{4}{5}{6}", banco.CodigoBanco, "-", banco.NomeBanco, "_", data, @"_REGISTRO_DETALHE", ".txt");

            //var arquivo = new System.IO.StreamWriter(path + @"\" + nomeArquivo, true);
            //arquivo.WriteLine(linhasEscrever);

            //arquivo.Close();
        }
        /// <summary>
        /// Método que escreve a mensagem variável com código de registro 2 (Recibo Sacado)
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private string EscreverMensagemVariavelReciboSacado(DetalheRemessaCnab400 info)
        {
            string complementoRegistro =
                info.ContaCorrente.Remove(0, info.ContaCorrente.Length - 1) +
                info.DvContaCorrente;

            // A primeira instrução é a instrução do sacado conforme layout do SANTANDER
            var primeiraInstrucao = info.Instrucoes.FirstOrDefault();

            var msgVariavel = new string(' ', 400);
            try
            {
                msgVariavel = msgVariavel.PreencherValorNaLinha(1, 1, "2");
                msgVariavel = msgVariavel.PreencherValorNaLinha(2, 17, string.Empty.PadRight(16, ' ')); // Uso do Banco
                //msgVariavel = msgVariavel.PreencherValorNaLinha(18, 21, string.Empty.PadRight(4, ' ')); // Código da Agência
                //msgVariavel = msgVariavel.PreencherValorNaLinha(22, 29, string.Empty.PadRight(8, ' ')); // Conta Movimento
                //msgVariavel = msgVariavel.PreencherValorNaLinha(30, 37, string.Empty.PadRight(8, ' ')); // Conta Cobrança
                msgVariavel = msgVariavel.PreencherValorNaLinha(18, 37, info.CodigoDeTransmissao.PadLeft(20, '0'));
                msgVariavel = msgVariavel.PreencherValorNaLinha(38, 47, string.Empty.PadRight(10, ' ')); // Uso do Banco
                msgVariavel = msgVariavel.PreencherValorNaLinha(48, 49, "01");
                msgVariavel = msgVariavel.PreencherValorNaLinha(50, 99, primeiraInstrucao != null
                    ? primeiraInstrucao.TextoInstrucao.PadRight(50, ' ')
                    : string.Empty.PadRight(50, ' '));
                msgVariavel = msgVariavel.PreencherValorNaLinha(100, 382, string.Empty.PadRight(283, ' '));
                // Uso do Banco
                msgVariavel = msgVariavel.PreencherValorNaLinha(383, 383, "i".ToUpper());
                msgVariavel = msgVariavel.PreencherValorNaLinha(384, 385, complementoRegistro);
                msgVariavel = msgVariavel.PreencherValorNaLinha(386, 394, string.Empty.PadLeft(9, ' '));
                _numeroSequencialDeRegistro += 1;
                _numeroAtualDeRegistro = _numeroSequencialDeRegistro;
                msgVariavel = msgVariavel.PreencherValorNaLinha(395, 400, _numeroSequencialDeRegistro.ToString().PadLeft(6, '0'));
            }
            catch (Exception e)
            {
                throw new Exception(
                            string.Format(
                                "<BoletoBr>{0}Falha na geração das MENSAGENS PARA O BOLETO no arquivo de REMESSA.",
                                Environment.NewLine), e);
            }

            return msgVariavel;
        }
        /// <summary>
        /// Método que escreve a mensagem variável com código de registro 3 (Ficha de Compensação)
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private string EscreverMensagemVariavelFichaCompensacao(DetalheRemessaCnab400 info)
        {
            var listaLinhas = PreparaLinhaMensagemVariavel(info);
            string registroAtual = string.Empty;

            if (listaLinhas != null)
            {
                foreach (var linha in listaLinhas)
                {
                    if (listaLinhas.Last() == linha)
                    {
                        registroAtual += linha;
                    }
                    else
                    {
                        registroAtual += linha + Environment.NewLine;
                    }
                }
            }

            return registroAtual;
        }
        public List<string> PreparaLinhaMensagemVariavel(DetalheRemessaCnab400 info)
        {
            string complementoRegistro =
                info.ContaCorrente.Remove(0, info.ContaCorrente.Length - 1) +
                info.DvContaCorrente;

            var lista = new List<string>();
            int cont = 3;
            if (info.Instrucoes.Count > 0)
            {
                info.Instrucoes.RemoveAt(0);
                foreach (var instrucaoAtual in info.Instrucoes)
                {
                    // Primeira Mensagem (Mensagem 1) Variável que irá constar na linha 2 do detalhe atual
                    var msgVariavel = new string(' ', 400);
                    try
                    {
                        msgVariavel = msgVariavel.PreencherValorNaLinha(1, 1, cont.ToString());
                        msgVariavel = msgVariavel.PreencherValorNaLinha(2, 17, string.Empty.PadRight(16, ' ')); // Uso do Banco
                        //msgVariavel = msgVariavel.PreencherValorNaLinha(18, 21, string.Empty.PadRight(4, ' ')); // Código da Agência
                        //msgVariavel = msgVariavel.PreencherValorNaLinha(22, 29, string.Empty.PadRight(8, ' ')); // Conta Movimento
                        //msgVariavel = msgVariavel.PreencherValorNaLinha(30, 37, string.Empty.PadRight(8, ' ')); // Conta Cobrança
                        msgVariavel = msgVariavel.PreencherValorNaLinha(18, 37, info.CodigoDeTransmissao.PadLeft(20, '0'));
                        msgVariavel = msgVariavel.PreencherValorNaLinha(38, 47, string.Empty.PadRight(10, ' ')); // Uso do Banco
                        msgVariavel = msgVariavel.PreencherValorNaLinha(48, 49, "01");
                        msgVariavel = msgVariavel.PreencherValorNaLinha(50, 99, instrucaoAtual != null
                            ? instrucaoAtual.TextoInstrucao.PadRight(50, ' ')
                            : string.Empty.PadRight(50, ' '));
                        msgVariavel = msgVariavel.PreencherValorNaLinha(100, 382, string.Empty.PadRight(283, ' '));
                            // Uso do Banco
                        msgVariavel = msgVariavel.PreencherValorNaLinha(383, 383, "i".ToUpper());
                        msgVariavel = msgVariavel.PreencherValorNaLinha(384, 385, complementoRegistro);
                        msgVariavel = msgVariavel.PreencherValorNaLinha(386, 394, string.Empty.PadLeft(9, ' '));
                        _numeroSequencialDeRegistro += 1;
                        _numeroAtualDeRegistro = _numeroSequencialDeRegistro;
                        msgVariavel = msgVariavel.PreencherValorNaLinha(395, 400, _numeroSequencialDeRegistro.ToString().PadLeft(6, '0'));
                        lista.Add(msgVariavel);
                        cont++;
                    }

                    catch (Exception e)
                    {
                        throw new Exception(
                            string.Format(
                                "<BoletoBr>{0}Falha na geração das MENSAGENS PARA O BOLETO no arquivo de REMESSA.",
                                Environment.NewLine), e);
                    }
                }
            }

            return lista;
        }
        public string EscreverDetalhe(DetalheRemessaCnab400 infoDetalhe)
        {
            int identificadorMulta = 0;
            if (infoDetalhe.PercentualMulta > 0)
                identificadorMulta = 4;

            /* Códigos de Carteira
             * 1 - Eletrônica com registro
             * 3 - Caucionada eletrônica
             * 4 - Cobrança sem registro
             * 5 - Rápida com registro
             * 6 - Caucionada rápida
             * 7 - Descontada eletrônica
             */

            var codigoCarteira = string.Empty;

            if (infoDetalhe.CarteiraCobranca == "101")
                codigoCarteira = "5";
            if (infoDetalhe.CarteiraCobranca == "102")
                codigoCarteira = "4";

            string enderecoSacado = string.Empty;
            string bairroSacado = string.Empty;
            string cidadeSacado = string.Empty;

            string nomeSacado = string.Empty;

            if (String.IsNullOrEmpty(infoDetalhe.EnderecoPagador))
                enderecoSacado.PadRight(40, ' ');
            else if (infoDetalhe.EnderecoPagador.Length > 40)
            {
                enderecoSacado = infoDetalhe.EnderecoPagador.Substring(0, 40).ToUpper();
            }
            else
                enderecoSacado = infoDetalhe.EnderecoPagador.PadRight(40, ' ').ToUpper();

            if (String.IsNullOrEmpty(infoDetalhe.BairroPagador))
                bairroSacado.PadRight(12, ' ');
            else
                if (infoDetalhe.BairroPagador.Length > 12)
                    bairroSacado = infoDetalhe.BairroPagador.Substring(0, 12).ToUpper();
                else
                    bairroSacado = infoDetalhe.BairroPagador.PadRight(12, ' ').ToUpper();

            if (String.IsNullOrEmpty(infoDetalhe.CidadePagador))
                cidadeSacado.PadRight(15, ' ');
            else
                if (infoDetalhe.CidadePagador.Length > 15)
                    cidadeSacado = infoDetalhe.CidadePagador.Substring(0, 15).ToUpper();
                else
                    cidadeSacado = infoDetalhe.CidadePagador.PadRight(15, ' ').ToUpper();

            if (String.IsNullOrEmpty(infoDetalhe.NomePagador))
                nomeSacado.PadRight(40, ' ');
            else
                if (infoDetalhe.NomePagador.Length > 40)
                    nomeSacado = infoDetalhe.NomePagador.Substring(0, 40).ToUpper();
                else
                    nomeSacado = infoDetalhe.NomePagador.PadRight(40, ' ').ToUpper();

            string complementoRegistro =
                infoDetalhe.ContaCorrente.Substring(infoDetalhe.ContaCorrente.Length - 1, 1) +
                infoDetalhe.DvContaCorrente;

            var detalhe = new string(' ', 400);
            try
            {
                detalhe = detalhe.PreencherValorNaLinha(1, 1, "1");
                // 01 - CPF
                // 02 - CNPJ
                detalhe = detalhe.PreencherValorNaLinha(2, 3, infoDetalhe.InscricaoCedente.Length == 11 ? "01" : "02");
                detalhe = detalhe.PreencherValorNaLinha(4, 17, infoDetalhe.InscricaoCedente.Replace(".", "").Replace("/", "").Replace("-", "").PadLeft(14, '0'));
                detalhe = detalhe.PreencherValorNaLinha(18, 37, infoDetalhe.CodigoDeTransmissao.PadLeft(20, '0')); //Versão 2.0 do layout

                //detalhe = detalhe.PreencherValorNaLinha(18, 21, infoDetalhe.Agencia.PadLeft(4, '0'));
                //detalhe = detalhe.PreencherValorNaLinha(22, 29, infoDetalhe.ContaCorrente.Substring(0, 8)); // Conta Movimento
                //detalhe = detalhe.PreencherValorNaLinha(30, 37, infoDetalhe.ContaCorrente.Substring(0, 8)); // Conta Cobrança

                const string doc = "DOC";
                var seuNumero = doc + infoDetalhe.NossoNumeroFormatado.PadRight(25 - doc.Length, ' ');

                detalhe = detalhe.PreencherValorNaLinha(38, 62, seuNumero);
                // NossoNumero com DV, pegar os 8 primeiros dígitos, da direita para esquerda ( para CNAB 400)
                detalhe = detalhe.PreencherValorNaLinha(63, 70, infoDetalhe.NossoNumeroFormatado.Replace("-", "").Substring(5, 8));

                if (infoDetalhe.DataLimiteConcessaoDesconto == DateTime.MinValue)
                    detalhe = detalhe.PreencherValorNaLinha(71, 76, string.Empty.PadLeft(6, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(71, 76, infoDetalhe.DataLimiteConcessaoDesconto.ToString("ddMMyy"));

                detalhe = detalhe.PreencherValorNaLinha(77, 77, string.Empty.PadLeft(1, ' '));
                detalhe = detalhe.PreencherValorNaLinha(78, 78, identificadorMulta.ToString());

                if (String.IsNullOrEmpty(infoDetalhe.PercentualMulta.ToString()))
                    detalhe = detalhe.PreencherValorNaLinha(79, 82, string.Empty.PadLeft(4, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(79, 82, infoDetalhe.PercentualMulta.ToString().PadLeft(4, '0'));

                detalhe = detalhe.PreencherValorNaLinha(83, 84, "00");
                detalhe = detalhe.PreencherValorNaLinha(85, 97, "0000000000000" /*Vl do título em outra unidade (consultar banco)*/);
                detalhe = detalhe.PreencherValorNaLinha(98, 101, string.Empty.PadLeft(4, ' '));

                detalhe = detalhe.PreencherValorNaLinha(102, 107, "000000");

                detalhe = detalhe.PreencherValorNaLinha(108, 108, codigoCarteira);
                detalhe = detalhe.PreencherValorNaLinha(109, 110, "01" /* Código da Ocorrência*/);
                detalhe = detalhe.PreencherValorNaLinha(111, 120, infoDetalhe.NumeroDocumento.PadRight(10, ' '));
                detalhe = detalhe.PreencherValorNaLinha(121, 126, infoDetalhe.DataVencimento.ToString("ddMMyy"));

                #region VALOR TOTAL

                detalhe = detalhe.PreencherValorNaLinha(127, 139, infoDetalhe.ValorBoleto.ToString("f").Replace(",", "").PadLeft(13, '0'));

                #endregion

                detalhe = detalhe.PreencherValorNaLinha(140, 142, "033");
                if (codigoCarteira == "5")
                    detalhe = detalhe.PreencherValorNaLinha(143, 147, infoDetalhe.Agencia.PadLeft(5, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(143, 147, string.Empty.PadLeft(5, '0'));
                detalhe = detalhe.PreencherValorNaLinha(148, 149, infoDetalhe.Especie.Sigla.Equals("DM") ? "01" : infoDetalhe.Especie.Codigo.ToString(CultureInfo.InvariantCulture));
                detalhe = detalhe.PreencherValorNaLinha(150, 150, "N");
                detalhe = detalhe.PreencherValorNaLinha(151, 156, infoDetalhe.DataEmissao.ToString("ddMMyy"));

                #region INSTRUÇÕES REMESSA

                var primeiraInstrucao = infoDetalhe.Instrucao1;
                var segundaInstrucao = infoDetalhe.Instrucao2;

                if (primeiraInstrucao != null)
                    detalhe = detalhe.PreencherValorNaLinha(157, 158, primeiraInstrucao);
                else
                    detalhe = detalhe.PreencherValorNaLinha(157, 158, "00");

                if (segundaInstrucao != null)
                    detalhe = detalhe.PreencherValorNaLinha(159, 160, segundaInstrucao);
                else
                    detalhe = detalhe.PreencherValorNaLinha(159, 160, "00");

                #endregion

                #region JUROS

                detalhe = detalhe.PreencherValorNaLinha(161, 173, infoDetalhe.ValorMoraDia.ToString("f").Replace(",", "").PadLeft(13, '0'));

                #endregion

                #region DESCONTO

                if (infoDetalhe.DataDesconto == DateTime.MinValue)
                    detalhe = detalhe.PreencherValorNaLinha(174, 179, string.Empty.PadLeft(6, '0'));
                else
                    detalhe = detalhe.PreencherValorNaLinha(174, 179, infoDetalhe.DataDesconto.ToString("ddMMyy"));

                detalhe = detalhe.PreencherValorNaLinha(180, 192, infoDetalhe.ValorDesconto.ToString("f").Replace(",", "").PadLeft(13, '0'));

                #endregion

                #region IOF

                detalhe = detalhe.PreencherValorNaLinha(193, 205, infoDetalhe.ValorIof.ToString("f").Replace(",", "").PadLeft(13, '0'));

                #endregion

                #region ABATIMENTO

                detalhe = detalhe.PreencherValorNaLinha(206, 218, infoDetalhe.ValorAbatimento.ToString("f").Replace(",", "").PadLeft(13, '0'));

                #endregion

                detalhe = detalhe.PreencherValorNaLinha(219, 220, infoDetalhe.InscricaoPagador.Length == 11 ? "01" : "02");
                detalhe = detalhe.PreencherValorNaLinha(221, 234, infoDetalhe.InscricaoPagador.Replace(".", "").Replace("/", "").Replace("-", "").PadLeft(14, '0'));
                detalhe = detalhe.PreencherValorNaLinha(235, 274, nomeSacado);
                detalhe = detalhe.PreencherValorNaLinha(275, 314, enderecoSacado);
                detalhe = detalhe.PreencherValorNaLinha(315, 326, bairroSacado);

                #region CEP

                var Cep = infoDetalhe.CepPagador;

                if (Cep.Contains(".") && Cep.Contains("-"))
                    Cep = Cep.Replace(".", "").Replace("-", "");
                if (Cep.Contains("."))
                    Cep = Cep.Replace(".", "");
                if (Cep.Contains("-"))
                    Cep = Cep.Replace("-", "");

                detalhe = detalhe.PreencherValorNaLinha(327, 334, Cep.PadLeft(8, '0'));

                #endregion

                detalhe = detalhe.PreencherValorNaLinha(335, 349, cidadeSacado);
                detalhe = detalhe.PreencherValorNaLinha(350, 351, infoDetalhe.UfPagador.PadRight(2, ' '));

                if (String.IsNullOrEmpty(infoDetalhe.NomeAvalistaOuMensagem2))
                    detalhe = detalhe.PreencherValorNaLinha(352, 381, string.Empty.PadRight(30, ' '));
                else
                    detalhe = detalhe.PreencherValorNaLinha(352, 381, infoDetalhe.NomeAvalistaOuMensagem2.PadRight(30, ' '));

                detalhe = detalhe.PreencherValorNaLinha(382, 382, " ");
                detalhe = detalhe.PreencherValorNaLinha(383, 383, "i".ToUpper()); // Identificador do Complemento
                detalhe = detalhe.PreencherValorNaLinha(384, 385, complementoRegistro);
                detalhe = detalhe.PreencherValorNaLinha(386, 391, string.Empty.PadLeft(6, ' '));
                detalhe = detalhe.PreencherValorNaLinha(392, 393, infoDetalhe.NroDiasParaProtesto.ToString().PadLeft(2, '0'));
                detalhe = detalhe.PreencherValorNaLinha(394, 394, " ");

                // TODO: Essa implementação não ficou legal mas está funcional..
                if (_numeroSequencialDeRegistro < infoDetalhe.NumeroSequencialRegistro)
                    _numeroSequencialDeRegistro = infoDetalhe.NumeroSequencialRegistro;
                else if (_numeroSequencialDeRegistro == _numeroAtualDeRegistro)
                    _numeroSequencialDeRegistro += 1;

                _numeroAtualDeRegistro = _numeroSequencialDeRegistro;
                detalhe = detalhe.PreencherValorNaLinha(395, 400, _numeroSequencialDeRegistro.ToString().PadLeft(6, '0'));

                return detalhe;
            }
            catch (Exception e)
            {
                throw new Exception(string.Format("<BoletoBr>{0}Falha na geração do DETALHE do arquivo de REMESSA.",
                    Environment.NewLine), e);
            }
        }