Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 2266 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Boa tarde Colegas,

Estou utilizando o ACBr para envio da remessa e retorno do banco Santander, mas no processamento do retorno encontrei um problema, ou talvez foi feito para ser assim (MotivoRejeicaoComando - somente motivos de rejeição).

Primeiro resumidamente é que o Motivo que vem no arquivo quando é liquidação ou baixa(Ocorrência 06 ou 09) ou  não está entrando na rotina Titulo.MotivoRejeicaoComando.Add. Assim não temos disponíveis os motivos das ocorrências na baixa/liquidação.

Versão mais detalhada: 

procedure TACBrBancoSantander.LerRetorno240

Layout: Santander - CNAB 240 - Layout de Arquivo - Padrão 240 – Cobrança - Versão 2.8.3 - Setembro/2017

Nota 41 -  Indica que o código de ocorrência 03(03 - Entrada rejeitada), 26(26 - instrução rejeitada) e 30(30 - alteração de dados rejeitada) estão relacionados com a nota 41-a
E os códigos 06(liquidação), 09(baixa) e 17 estão relacionados com a nota 41-C
- Ai temos uma relação - Códigos de rejeições de 01 a 64 associados ao códigos de movimento 03, 26 e 30
- E temos uma relação de Código de liquidação/baixa de 01 a 13 associados ao código de movimento 06, 09 e 17

Bom, analisando um arquivo de retorno do Santander, no segmento, T, na coluna 209(Motivo), quando a ocorrência vem 06(Liquidação) veio os motivos 03(No próprio banco) e 04(Compensação eletrônica).

Ai analisando o arquivo do Acbr ( ACBrBancoSantander.pas ) verifiquei que na leitura do retorno na procedure TACBrBancoSantander.LerRetorno240 - DoVerOcorrencia
Só tem a tratativa dos motivos das ocorrências 03, 26 e 30, as quais estão ligadas somente as rejeições. 

if MatchText(AOcorrencia, ['03', '26', '30'])  then

Mas eu preciso dos motivos das ocorrências 06, 09 e 17, principalmente da 06 e 09
Então minha sugestão de alteração do código seria: 

      if MatchText(AOcorrencia, ['03', '06', '09', '17', '26', '30'])  then
      begin
       pMotivoRejeicao:= 209;
       for I:= 0 to 4 do
       begin
         CodMotivo:= StrToIntDef(copy(Linha,pMotivoRejeicao,2),0);
         if CodMotivo > 0 then
         begin
           Titulo.MotivoRejeicaoComando.Add(copy(Linha, pMotivoRejeicao, 2));
           Titulo.DescricaoMotivoRejeicaoComando.Add(CodMotivoRejeicaoToDescricao(
                                                     Titulo.OcorrenciaOriginal.Tipo,CodMotivo));
         end;
         Inc(pMotivoRejeicao, 2);
       end;
       if AOcorrencia = '03' then
         Tipo:= toRetornoRegistroRecusado
       else if AOcorrencia = '26' then
         Tipo := toRetornoInstrucaoRejeitada
       else if AOcorrencia = '30' then
         Tipo := toRetornoAlteracaoDadosRejeitados
       else if MatchText(AOcorrencia, ['06', '09'])  then
         Tipo := CodOcorrenciaToTipo(StrToInt(AOcorrencia))
       else if AOcorrencia = '17' then
          Tipo := toRetornoLiquidadoAposBaixaOuNaoRegistro
      end

Ou seja incluir no primeiro if o '06', '09', '17'... 

E colocar no if do Tipo adicionar o 06 , 09 e 17. os quais puxei de baixo onde ele entrava antes.

Ver a possibilidade de alteração para que possamos ter os motivos nas ocorrências: (09-baixa ou 06-liquidação) ou se MotivoRejeicaoComando é somente para rejeições e não tem a opção de pegar o motivo quando da baixa.

Mas iria enviar o arquivo em anexo do fonte atualizado (2018.05.30) com a alteração mencionada, caso MotivoRejeicaoComando não seja somente rejeição.

Mas fui testar a modificação e ai descobri que os códigos de motivos que retornam são os códigos do layout 400.

Layout: PRODUTOS RECEBIMENTOS - CNAB 400 (padrão Santander)  - Com Registro - Versão 2.17 – Outubro/2017

 Página 22 - Nota 13: Códigos de Ocorrências - temos os códigos com 3 dígitos - e na 240 temos com dois dígitos o motivo.

Então, seguindo o padrão do ACBrBancoBrasil.pas eu cadastrei os códigos dos motivos para o CNAB 240.

Então tive que mudar na procedure TACBrBancoSantander.LerRetorno240 - DoVerOcorrencia

Esse código :

       if AOcorrencia = '03' then
         Tipo:= toRetornoRegistroRecusado
       else if AOcorrencia = '26' then
         Tipo := toRetornoInstrucaoRejeitada
       else if AOcorrencia = '30' then
         Tipo := toRetornoAlteracaoDadosRejeitados
       else if MatchText(AOcorrencia, ['06', '09'])  then
         Tipo := CodOcorrenciaToTipo(StrToInt(AOcorrencia))
       else if AOcorrencia = '17' then
          Tipo := toRetornoLiquidadoAposBaixaOuNaoRegistro;

Antes do código da rejeição, pois é necessário saber o Tipo na rotina CodMotivoRejeicaoToDescricao, então ficou assim esse trecho: 

     if MatchText(AOcorrencia, ['03', '06', '09', '17', '26', '30'])  then
      begin
       if AOcorrencia = '03' then
         Tipo:= toRetornoRegistroRecusado
       else if AOcorrencia = '26' then
         Tipo := toRetornoInstrucaoRejeitada
       else if AOcorrencia = '30' then
         Tipo := toRetornoAlteracaoDadosRejeitados
       else if MatchText(AOcorrencia, ['06', '09'])  then
         Tipo := CodOcorrenciaToTipo(StrToInt(AOcorrencia))
       else if AOcorrencia = '17' then
          Tipo := toRetornoLiquidadoAposBaixaOuNaoRegistro;
       pMotivoRejeicao:= 209;
       for I:= 0 to 4 do
       begin
         CodMotivo:= StrToIntDef(copy(Linha,pMotivoRejeicao,2),0);
         if CodMotivo > 0 then
         begin
           Titulo.MotivoRejeicaoComando.Add(copy(Linha, pMotivoRejeicao, 2));
           Titulo.DescricaoMotivoRejeicaoComando.Add(CodMotivoRejeicaoToDescricao(
                                                     Titulo.OcorrenciaOriginal.Tipo,CodMotivo));
         end;
         Inc(pMotivoRejeicao, 2);
       end;

Bom agora a mudança no procedimento CodMotivoRejeicaoToDescricao somente a parte do else para o CNAB 240:

else // 240
  begin
  case TipoOcorrencia of
    toRetornoComandoRecusado: //03 (Entrada rejeitada)
      case CodMotivo of
        01: Result:='Codigo do banco invalido';
        02: Result:='Codigo do registro detalhe invalido';
        03: Result:='Codigo do segmento invalido';
        04: Result:='Codigo do movimento nao permitido para carteira';
        05: Result:='Codigo de movimento invalido';
        06: Result:='Tipo/numero de inscricao do beneficiário invalidos';
        07: Result:='Agencia/Conta/DV invalido';
        08: Result:='Nosso numero invalido';
        09: Result:='Nosso numero duplicado';
        10: Result:='Carteira invalida';
        11: Result:='Forma de cadastramento do titulo invalido';
        12: Result:='Tipo de documento invalido';
        13: Result:='Identificacao da emissao do bloqueto invalida';
        14: Result:='Identificacao da distribuicao do bloqueto invalida';
        15: Result:='Caracteristicas da cobranca incompativeis';
        16: Result:='Data de vencimento invalida';
        17: Result:='Data de vencimento anterior a data de emissao';
        18: Result:='Vencimento fora do prazo de operacao';
        19: Result:='Titulo a cargo de Bancos Correspondentes com vencimento inferior XX dias';
        20: Result:='Valor do titulo invalido';
        21: Result:='Especie do titulo invalida';
        22: Result:='Especie nao permitida para a carteira';
        23: Result:='Aceite invalido';
        24: Result:='Data da emissao invalida';
        25: Result:='Data da emissao posterior a data';
        26: Result:='Codigo de juros de mora invalido';
        27: Result:='Valor/Taxa de juros de mora invalido';
        28: Result:='Codigo do desconto invalido';
        29: Result:='Valor do desconto maior ou igual ao valor do titulo ';
        30: Result:='Desconto a conceder nao confere';
        31: Result:='Concessao de desconto - ja existe desconto anterior';
        32: Result:='Valor do IOF invalido';
        33: Result:='Valor do abatimento invalido';
        34: Result:='Valor do abatimento maior ou igual ao valor do titulo';
        35: Result:='Abatimento a conceder nao confere';
        36: Result:='Concessao de abatimento - ja existe abatimento anterior';
        37: Result:='Codigo para protesto invalido';
        38: Result:='Prazo para protesto invalido';
        39: Result:='Pedido de protesto nao permitido para o titulo';
        40: Result:='Titulo com ordem de protesto emitida';
        41: Result:='Pedido de cancelamento/sustacao para titulos sem instrucao de protesto';
        42: Result:='Codigo para baixa/devolucao invalido';
        43: Result:='Prazo para baixa/devolucao invalido';
        44: Result:='Codigo da moeda invalido';
        45: Result:='Nome do pagador nao informado';
        46: Result:='Tipo/numero de inscricao do pagador invalidos';
        47: Result:='Endereco do pagador nao informado';
        48: Result:='CEP invalido';
        49: Result:='CEP sem praca de cobranca /nao localizado';
        50: Result:='CEP referente a um Banco Correspondente';
        51: Result:='CEP incompativel com a unidade da federacao';
        52: Result:='Unidade da federacao invalida';
        53: Result:='Tipo/numero de inscricao do sacador/avalista invalidos';
        54: Result:='Sacador/Avalista nao informado';
        55: Result:='Nosso numero no Banco Correspondente nao informado';
        56: Result:='Codigo do Banco Correspondente nao informado';
        57: Result:='Codigo da multa invalido';
        58: Result:='Data da multa invalida';
        59: Result:='Valor/Percentual da multa invalido';
        60: Result:='Movimento para titulo nao cadastrado';
        61: Result:='Alteracao da agencia cobradora/dv invalida';
        62: Result:='Tipo de impressao invalido';
        63: Result:='Entrada para titulo ja cadastrado';
        64: Result:='Numero da linha invalido';
        65: Result:='A espécie de título não permite a instrução';
        72: Result:='Entrada de título Sem Registro';
        90: Result:='Identificador/Quantidade de Parcelas de carnê invalido';
        92: Result:='Data de Desconto Inválida';
      end;
    toRetornoLiquidadoSemRegistro, toRetornoLiquidado, toRetornoLiquidadoPorConta,
       toRetornoLiquidadoSaldoRestante, toRetornoLiquidadoEmCartorio: // 05, 06, 07, 08 e 15 (Liquidado)
      case CodMotivo of
        01: Result:='01-Por saldo';
        02: Result:='02-Por conta';
        03: Result:='03-No próprio banco';
        04: Result:='04-Compensação eletrônica';
        05: Result:='05-Compensação convencional';
        06: Result:='06-Arquivo magnético';
        07: Result:='07-Após feriado local';
        08: Result:='08-Em cartório';
        09: Result:='09-Pagamento Parcial';
      end;
    else
      Result := IntToStrZero(CodMotivo, 2) + ' - Outros Motivos';
  end; //case TipoOcorrencia

  end; //else 240

Assim eu consegui ler código do motivo quando a ocorrência vem como liquidado.

Como disse não sei se o MotivoRejeicaoComando utiliza somente rejeição, mas a julgar pelo fonte do banco do Brasil, acredito que não, assim  esse correção seria interessante.

Estou enviando o fonte do Acbr do Santander para análise para verificar a possível alteração. 

Caso precisem dos manuais também posso disponibiliza-los aqui.

Nos testes que fiz aqui deram certo.

Abraços,

Rodrigo

ACBrBancoSantander.pas

Rodrigo ®¿®

Curitiba-PR

  • Administradores
Postado

Bom dia.

Alteração adicionada a fila para análise.

Att.

Consultora SAC ACBr

Juliana Tamizou

Gerente de Projetos ACBr / Diretora de Marketing AFRAC
Ajude o Projeto ACBr crescer - Seja Pro

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  Discord

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil


Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

  • 4 semanas depois ...
  • 2 meses depois ...
  • Solution
Postado

Desculpe voltar no passado, mas vendo o código proposto pelo nosso amigo, percebi que o retorno quando ocorre rejeição esta sempre vindo "Outros Motivos".

Parece que o problema está neste trecho do código.

    end
  else // 240
  begin
    case TipoOcorrencia of
    toRetornoComandoRecusado: //03 (Entrada rejeitada)
      case CodMotivo of

 

Mudei para 

 

end
  else // 240
  begin
    case TipoOcorrencia of
    toRetornoComandoRecusado, toRetornoRegistroRecusado: //03 (Entrada rejeitada)
      case CodMotivo of

 

Dessa forma o motivo da recusa veio corretamente.

 

 

  • 2 semanas depois ...
  • Moderadores
Postado
Em 30/08/2018 at 17:34, aslsoftware disse:

Desculpe voltar no passado, mas vendo o código proposto pelo nosso amigo, percebi que o retorno quando ocorre rejeição esta sempre vindo "Outros Motivos".

Parece que o problema está neste trecho do código.

    end
  else // 240
  begin
    case TipoOcorrencia of
    toRetornoComandoRecusado: //03 (Entrada rejeitada)
      case CodMotivo of

 

Mudei para 

 

end
  else // 240
  begin
    case TipoOcorrencia of
    toRetornoComandoRecusado, toRetornoRegistroRecusado: //03 (Entrada rejeitada)
      case CodMotivo of

 

Dessa forma o motivo da recusa veio corretamente.

 

 

Bom dia, correção atualizada no SVN. Obrigado! 

  • Curtir 1
Consultor SAC ACBr

José Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

  • Este tópico foi criado há 2266 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.