Ir para conteúdo
  • Cadastre-se

  • Este tópico foi criado há 2843 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

  • Consultores
Postado

Bom dia.

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

Att.

Consultora ACBr Pro

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á 2843 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.

The popup will be closed in 10 segundos...
The popup will be closed in 10 segundos...