Ir para conteúdo
  • Cadastre-se

mlgoncalves

Membros
  • Total de ítens

    73
  • Registro em

  • Última visita

Tudo que mlgoncalves postou

  1. Olá pessoal, O grupo GerarJuros do JSON está com erro no preenchimento do campo 'tipoJurosMora'. TACBrCodigoJuros = (cjValorDia, cjTaxaMensal, cjIsento, cjValorMensal, cjTaxaDiaria); Integer(aTitulo.CodigoMoraJuros) retorna cjValorDia = 0 -------->>>>> no JSON deve ser informado 1 vjTaxaMensal = 1 --------->>>>>>> no JSON deve ser informado 2 Transcrição do código que está no SVN com erro e a proposta de correção: case (StrToIntDef(aTitulo.CodigoMora, 0)) of 0: // Isento begin AJson.Add('tipoJurosMora').Value.AsInteger := 0; AJson.Add('valorJurosMora').Value.asNumber := 0; end; 1: // Dia begin // AJson.Add('taxa').Value.asNumber := aTitulo.ValorMoraJuros; AJson.Add('tipoJurosMora').Value.AsInteger := Integer(aTitulo.CodigoMoraJuros); <<<<<<----- Corrigir esta linha anotando o número 1 (um). A função retorna 0 (zero); AJson.Add('dataJurosMora').Value.asString := DateTimeToDateBancoob(aTitulo.DataMulta); AJson.Add('valorJurosMora').Value.asNumber := aTitulo.ValorMoraJuros; end; 2: // Mês begin AJson.Add('tipoJurosMora').Value.AsInteger := Integer(aTitulo.CodigoMoraJuros); <<<<<<<<------- Corrigir esta linha anotando o número 2 (dois). A função retorna 1 (um); AJson.Add('dataJurosMora').Value.asString := DateTimeToDateBancoob(aTitulo.DataMulta); AJson.Add('valorJurosMora').Value.asNumber := aTitulo.ValorMoraJuros; end; end; Atenciosamente, Marcelo Gonçalves
  2. Olá Victor, acabei de atualizar os fontes pelo SVN e entendo que a modificação feita não atende o requisito. Modificação feita: case HttpResultCode of 207: begin aJsonViolacoes := aJson.Values['resultado'].AsArray; for x := 0 to aJsonViolacoes.Count -1 do begin aJsonViolacao := aJsonViolacoes[x].AsObject; aJsonViolacoes := aJsonViolacao['status'].AsArray; ARejeicao := ARetornoWS.CriarRejeicaoLista; ARejeicao.Codigo := aJsonViolacao.Values['codigo'].AsString; ARejeicao.mensagem := aJsonViolacao.Values['mensagem'].AsString; end; end; 400,406,500 : begin aJsonViolacoes := aJson.Values['mensagens'].AsArray; for x := 0 to aJsonViolacoes.Count -1 do begin aJsonViolacao := aJsonViolacoes[x].AsObject; ARejeicao := ARetornoWS.CriarRejeicaoLista; ARejeicao.Codigo := AJsonViolacao.Values['codigo'].AsString; ARejeicao.mensagem := AJsonViolacao.Values['mensagem'].AsString; end; end; end; Onde está o problema no meu ponto de vista: HTTPResultCode=207 indica tanto sucesso de registro de boleto quanto erro. Não acho correto preencher a lista de violações de regras sendo que quando o boleto é registrado não houve violação de nenhuma regra. Insisto que quando aJsonViolacao.Values['codigo'].AsString estiver retormadp com 200, nada a fazer, boleto registrado com sucesso. Quando retornado com 400 aí sim tem problema a ser corrigido.
  3. Olá pessoal, Entendo que existe erro no preenchimento o campo SEUNUMERO no JSON gerado pela unid ACBrBoletoW_Bancoob.pas. Está preenchendo neste campo o valor de NossoNumero e entendo que deveria ser SeuNumero. Cópia das linhas o arquivo original: Json.Add('nossoNumero').Value.AsString := OnlyNumber(aTitulo.ACBrBoleto.Banco.MontarCampoNossoNumero(aTitulo)); Json.Add('seuNumero').Value.asString := OnlyNumber(aTitulo.ACBrBoleto.Banco.MontarCampoNossoNumero(aTitulo)); //ATitulo.SeuNumero; Json.Add('identificacaoBoletoEmpresa').Value.AsString := OnlyNumber(aTitulo.ACBrBoleto.Banco.MontarCampoNossoNumero(aTitulo)); Copia das linhas propostas para correção: Json.Add('nossoNumero').Value.AsString := OnlyNumber(aTitulo.ACBrBoleto.Banco.MontarCampoNossoNumero(aTitulo)); Json.Add('seuNumero').Value.asString := ATitulo.SeuNumero; Json.Add('identificacaoBoletoEmpresa').Value.AsString := ATitulo.SeuNumero; Entendo que o componente deva ser coerente no preenchimento dos campos. Se houver alguma necessidade de particularizar o conteúdo dos campos isso deve ser tratado na aplicação. ACBrTituloNaAplicacao.SeuNumero := 'ID DO BOLETO NO BANCO DE DADOS DA APLICACAO'; ou se preferir 'NOSSO NÚMERO DO BOLETO' ACBrTituloNaAplicacao.NossoNumero := 'NOSSO NÚMERO DO BOLETO'; IdentificacaoBoletoEmpresa Não existe na classe TACBrTitulo, então o componente pode arbitrar o que deve ser preenchido: ou o nosso número (acho isso menos lógico) ou o seu número (acho essa escolha a mais lógica) Atenciosamente, Marcelo Gonçalves
  4. Olá pessoal, O HttpResultCode=207 é código retornado com sucesso do banco Sicoob tanto para indicar registro de boleto quando para indicar erros de preenchimento. Então é necessário tratar corretamente o JSON retornado para o preenchimento da lista dos erros retornados, se houver. Arquivos anexados: ACBrBoletoRet_Bancoob.pas -> alterado com o ajuste JSON com erro de retorno.json -> arquivo original retornado pelo Sicoob no código HttpResultCode=207 porém informando rejeição por erro de preenchimento do boleto JSON de boleto registrado.json -> arquivo original retornado pelo Sicoob no código HttpResultCode=207 de boleto registrado Atenciosamente, Marcelo Gonçalves ACBrBoletoRet_Bancoob.pas JSON com erro de retorno.json JSON de boleto registrado.json
  5. Sergio_api, a unit que postei acima está redondinha. É pegar e usar. Vamos aguardar a revisão para disponibilizarem no repositório. Marcelo.
  6. Olá pessoal! Estou dedicado em tentar finalizar a cobrança Sicoob através de API e me deparei com as seguintes situações que entendo devam ser atualizadas no repositório (segue em anexo unit devidamente modificada): Arquivo: ACBrBoletoW_Bancoob.pas 1) Formato da data, linhas 269/270 SVN: result := FormatDateBr( aValue, 'YYYY-MM-DD') + 'T' + FormatDateTime('hh:nn:ss', AValue) + PegaTimeZone; //'2023-05-26T03:00:00.000Z' - versão acbr - fora do formato esperado SOLUÇÃO PROPOSTA (não é desenvolvimento meu, mas de versões anteriores que está funcionando corretamente): result := FormatDateBr( aValue, 'YYYY-MM-DD') + 'T' + FormatDateTime('hh:nn:ss', AValue) + PegaTimeZone; //'2023-05-26T00:00:00-03:00' - correto, dentro do padrão definido pelo SICOOB function TBoletoW_Bancoob.PegaTimeZone: string; var TimeZone: TTimeZoneInformation; begin GetTimeZoneInformation(TimeZone); Result := FormatFloat('00', TimeZone.Bias div -60) + ':00'; end; 2) Rotina de geração do juros de mora procedure TBoletoW_Bancoob.GerarJuros(AJson: TJsonObject); begin if Assigned(aTitulo) then begin if Assigned(AJson) then begin if (aTitulo.ValorMoraJuros > 0) then begin if ATitulo.CodigoMora = '' then begin case aTitulo.CodigoMoraJuros of cjValorDia : aTitulo.CodigoMora := '1'; cjTaxaMensal : aTitulo.CodigoMora := '2'; cjIsento : aTitulo.CodigoMora := '0'; end; end; case (StrToIntDef(aTitulo.CodigoMora, 0)) of 0: // Isento begin AJson.Add('tipoJurosMora').Value.AsInteger := 0; AJson.Add('valorJurosMora').Value.asNumber := 0; end; 1: // Dia begin // AJson.Add('taxa').Value.asNumber := aTitulo.ValorMoraJuros; AJson.Add('tipoJurosMora').Value.AsInteger := 1; <<<<<<------ Isso está correto. A função do repositório Integer(aTitulo.CodigoMoraJuros) retorna o valor 0 (zero) AJson.Add('dataJurosMora').Value.asString := DateTimeToDateBancoob(aTitulo.DataMulta); AJson.Add('valorJurosMora').Value.asNumber := aTitulo.ValorMoraJuros; end; 2: // Mês begin AJson.Add('tipoJurosMora').Value.AsInteger := 2; <<<<<<------ Isso está correto. A função do repositório Integer(aTitulo.CodigoMoraJuros) retorna o valor 1 (um) AJson.Add('dataJurosMora').Value.asString := DateTimeToDateBancoob(aTitulo.DataMulta); AJson.Add('valorJurosMora').Value.asNumber := aTitulo.ValorMoraJuros; end; end; end; end; end; end; Atenciosamente, ACBrBoletoW_Bancoob.pas
  7. Olá Pedro, Utilizei os fontes que você disponibilizou e ainda não consegui gerar o token de autorização, necessário para utilização da API. No Postman eu consigo gerar o token, mas para isso tive de configurar o certificado digital informando os arquivos .CRT e .KEY. Tentei fazer exatamente o mesmo nos exemplos do ACBR, mas parece que está faltando alguma coisa pois não gera o token de jeito nenhum. Você tem alguma dica pra passar? Desde já agradeço. Marcelo Gonçalves
  8. Me ajuda numa coisa: onde informo o HOST 'https://auth.sicoob.com.br' que é necessário para a obtenção do token?
  9. Olá Marcelo Santos, você está conseguindo fazer o registro on-line através deste código? Estou fazendo testes e não estou tendo sucesso em obter o token de autorização.
  10. Prezados, bom dia! Favor incluir a espécie de título 'Boleto de Proposta', sigla 'BDP', código '32' para layout CNAB400, conforme demonstrado na imagem abaixo e conforme consta no arquivo de documentação do Banco do Bradesco que existe no repositório '..\Branches\tools\Bancos\237-Bradesco\CNAB400_Cobranca_2021_VER001_01_04_2021.pdf' Em anexo está o arquivo com a alteração. Atenciosamente, Marcelo Gonçalves ACBrBoleto.pas
  11. Olá ToninhoNunes, Vou verificar agora e retorno aqui.
  12. Bom dia, Antonio Gomes! Obrigado pela atenção. Vou fazer os testes de leitura dos códigos de barra e retorno depois. Atc, Marcelo.
  13. Prezados bom dia! Não estamos conseguindo ler o código de barras do boleto. Utilizamos FastReport e testamos a leitura com todos os layouts disponíveis e conseguimos sucesso apenas com o layout BoletoCarne, os demais não estão lendo. Testamos a leitura tanto na tela quanto no modelo impresso. Outro teste que fizemos foi de imprimir segunda via diretamente do site do banco (no caso utilizamos o Santanter para teste). Testamos a leitura do código de barras do boleto impresso do banco e ok, lido com sucesso. Mas do boleto impresso pelo ACBR não conseguimos ler. Seria alguma configuração no componente a ser feita? Não localizamos nada que pudesse interferir nisso. Se puderem ajudar, agradeçemos. Marcelo.
  14. Prezados, boa tarde! Segue a unit ACBrPagForGravarTxt.pas que contém as configurações para geração do arquivo no padrão do Banco do Brasil. Favor verificar e se julgarem pertinentes as mudanças, incluir no projeto. ACBrPagForGravarTxt.rar Atenciosamente, Marcelo
  15. Boa tarde! Segue em anexo unit ACBrPagForLerTxt.pas revisada. Por favor verifiquem e se jugarem pertinentes as alterações favor publicar. Atenciosamente, MarceloACBrPagForLerTxt.rar
  16. Obrigado pelo retorno. Ainda estamos desenvolvendo o componente para gerar arquivo do Banco do Brasil. Assim que finalizar os testes iremos subir os novos fontes. Atenciosamente, Marcelo
  17. Prezados colegas, não encontrei um grupo específico do ACBRPagFor e por isso abri este tópico aqui mesmo. Estava fazendo uns testes de leitura de arquivos de retorno e percebi que o método LerTxt estava incompleto. Então decidi fazer algumas modificações listadas na unit em anexo que parece estar funcionando corretamente. O banco que estou trabalhando o retorno é o Banco do Brasil. Ainda não revisei a geração do arquivo remessa. Quem quiser colaborar fique à vontade. Atc,Frm_ACBrPagFor_Exemplo.rar Marcelo Gonçalves Lógica da leitura dos registros no arquivo. Existem registros de segmentos diferentes (A, J, O, etc) que possuem segmentos opcionais em comum (o segmento A pode ter segmentos opcionais B e Z; o segmento J pode ter segmentos opcionais B, C, D, E, F, Z; e assim por diante. Então para fazer uma leitura correta de um TXT estou lendo a linha do segmento principal e dentro da mesma rotina continuo incrementando o índice das linhas para avançar para as próximas linhas de segmento opcional, se houver. É isso. Não sou especialista em Delphi. Fiquem à vontade para aprimorar a escrita do código. Oportunamente estou anexando o exemplo que lê os arquivos. ACBrPagForLerTxt.rar ACBrPagForConversao.rar
  18. Fernando, obrigado pelo retorno. Analisei a unit, que por sinal está bem sinalizada com as suas intervenções, mas ainda a leitura do arquivo TXT retornado do banco está incompleta. Não consigo ler o segmento opcional Z do segmento O. Você pode tentar fazer a leitura do arquivo e verificar se o segmento opcional Z foi lido? Vou enviar o arquivo em anexo. segmento o.rar
  19. Olá Fernando, estou com o mesmo problema. No meu caso o banco em questão é o Banco do Brasil. Tenho vários retornos de diversos segmentos, mas não estou conseguindo ler completamente o retorno (digo dos segmentos opcionais). Você já evoluiu nesse assunto?
  20. Olá Fernando, desculpe mas somente agora vi sua citação. Podemos então falar sobre a API do BB para boletos e outros? Já finalizei a API do SICOOB. Marcelo
  21. Olá gtvosouza, tudo bem? Estou iniciando a implementação da API do Banco do Brasil para geração de boletos. Tenho experiência no ACBRBoleto, mas não é por esse caminho que desejo seguir, mas sim pela API do banco. Você poderia compartilhar o que você já tem implementado para eu analisar? Também estou abrindo acesso técnico no SICOOB para implementação da API. Caso tenha interesse posso compartilhar o projeto. Obrigado, Marcelo.
  22. Olá, Segue em anexo a unit alterada. Atc, Marcelo. ACBrBoletoW_Caixa.pas
  23. Olá José Jr, obrigado pelo retorno. Segue mais uma sugestão para ser analisada na geração do XML webservice boleto caixa. Existe a TAG POS_VENCIMENTO onde deve-se informar o que deverá ser feito após o vencimento: protestar ou devolver o título. Na programação existente está sendo utilizado o campo 'DiasDeProtesto' para preencher a tag 'NUMERO_DIAS'. Acho que não deveria utilizar este campo para situação em que não haja protesto, pois gera inconsistência de informação na hora de imprimir o boleto. No webservice vai informação de baixa e no boleto aparece informação de protesto mesmo não havendo protesto. Segue abaixo o código original e a minha sugestão, que entendo ser mais acertada. //Versão original procedure TBoletoW_Caixa.GerarPos_Vencimento; begin if Assigned(Titulos) then with Titulos do begin Gerador.wGrupo('POS_VENCIMENTO'); if (integer(CodigoNegativacao) in [1,2]) then Gerador.wCampo(tcStr, '#14', 'ACAO ', 01, 20, 1, 'PROTESTAR', DSC_CODIGO_NEGATIVACAO) else Gerador.wCampo(tcStr, '#14', 'ACAO ', 01, 20, 1, 'DEVOLVER', DSC_CODIGO_NEGATIVACAO); Gerador.wCampo(tcInt, '#15', 'NUMERO_DIAS', 03, 03, 1, DiasDeProtesto, DSC_DIAS_PROTESTO); Gerador.wGrupo('/POS_VENCIMENTO'); end; end; //versão proposta para resolver o problema procedure TBoletoW_Caixa.GerarPos_Vencimento; var ADiasBaixaDevolucao: integer; begin if Assigned(Titulos) then with Titulos do begin Gerador.wGrupo('POS_VENCIMENTO'); if (integer(CodigoNegativacao) in [1,2]) then begin Gerador.wCampo(tcStr, '#14', 'ACAO ', 01, 20, 1, 'PROTESTAR', DSC_CODIGO_NEGATIVACAO); Gerador.wCampo(tcInt, '#15', 'NUMERO_DIAS', 03, 03, 1, DiasDeProtesto, DSC_DIAS_PROTESTO); end else begin if DataBaixa > Vencimento then ADiasBaixaDevolucao := Trunc(DataBaixa) - Trunc(Vencimento) else aDiasBaixaDevolucao := 0; Gerador.wCampo(tcStr, '#14', 'ACAO ', 01, 20, 1, 'DEVOLVER', DSC_CODIGO_NEGATIVACAO); Gerador.wCampo(tcInt, '#15', 'NUMERO_DIAS', 03, 03, 1, ADiasBaixaDevolucao, DSC_DIAS_PROTESTO); end; Gerador.wGrupo('/POS_VENCIMENTO'); end; end; Atenciosamente, Marcelo.
  24. Boa tarde! Estou colocando em produção o boleto via webservice da Caixa e encontrei algumas situações que descrevo abaixo com algumas propostas de alteração ou adaptação no código do acbr. 1) campo/tag xml 'IDENTIFICACAO_EMPRESA': entendo que neste campo deverá ser preenchido com o valor usado pela empresa(software) para identificar unicamente o boleto. Este campo é equivalente ao campo 'Seu Numero' no arquivo remessa. Acho que este campo está sendo confundido com o campo NumeroDocumento. Diante disso proponho as seguintes alterações: a) Linha 413 do arquivo ACBrBoletoW_Caixa.pas: Trocar o campo NumeroDocumento para SeuNumero Criar a constante DSC_SEU_NUMERO (isso eu não fiz no arquivo anexado) b) Linha 167 do arquivo ACBrBoletoRet_Caixa.pas Trocar o campo NumeroDocumento para SeuNumero 2) o campo ESPECIEDOC é preenchido originalmente por letras (vide a geração do arquivo remessa que converte letras para números) que identificam o seu conteúdo: DM=Duplicata mercantil/ OU=outros/ etc. Ocorre que a unit do webservice está informando diretamente o campo que gera erro. Proposta: na unit ACBrBoletoW_Caixa.pas na procedure TBoletoW_Caixa.GerarTitulo utilizar a conversão exatamente como é feito no arquivo remessa. Trecho do código: //mantendo padronização de preenchimento do campo EspecieDoc entre //as funcionalides de REMESSA e REGISTRO ON-LINE. //o campo EspecieDoc é preenchido com letras e nas respectivas funções de //REMESSA ou de REGISTRO ele é convertido para código if AnsiSameText(EspecieDoc, 'CH') then AEspecieDoc := '01' else if AnsiSameText(EspecieDoc, 'DM') then AEspecieDoc := '02' ... else AEspecieDoc := '99'; Gerador.wGrupo('TITULO'); Gerador.wCampo(tcStr, '#02', 'NOSSO_NUMERO ', 17, 17, 1, '14' + ACBrUtil.PadLeft(NossoNumero, 15, '0'), DSC_NOSSO_NUMERO); Gerador.wCampo(tcStr, '#03', 'NUMERO_DOCUMENTO', 11, 11, 1, NumeroDocumento, DSC_NUMERO_DOCUMENTO); Gerador.wCampo(tcDat, '#04', 'DATA_VENCIMENTO ', 10, 10, 1, Vencimento, DSC_DATA_VENCIMENTO); Gerador.wCampo(tcDe2, '#05', 'VALOR ', 01, 15, 1, ValorDocumento, DSC_VALOR_DOCUMENTO); Gerador.wCampo(tcStr, '#06', 'TIPO_ESPECIE ', 02, 02, 1, AEspecieDoc, DSC_TIPO_ESPECIE); 3) 'string de autenticacao': o campo NossoNumero faz parta da string de autenticação do boleto e deve iniciar obrigatoriamente com o número 14. Minha sugestão é que esse número inicial 14 seja adicionado opcionalmente caso o nosso número esteja incompleto. Trecho do código da unit ACBrBoletoW_Caixa.pas, function TBoletoW_Caixa.GerarAutenticacao var sAutenticacao, sNossoNumero: string; begin if length(NossoNumero) = 17 then sNossoNumero := NossoNumero else //adicionar o prefixo 14 no nosso número sNossoNumero := '14' + ACBrUtil.PadLeft(NossoNumero, 15, '0'); 4) geração do HASH da autenticação: sou usuário do Delphi XE6 e nesta versão o cálculo do HASH existente na função TBoletoW_Caixa.GerarAutenticacao não funciona. Recorri ao fórum do ACBR onde encontrei uma função que resolveria o problema mas ocorre que a função faz uso da units System.NetEncoding.pas e System.Hash.pas, ausentes no Delphi XE6. Para resolver o problema copiei estas units de um Delphi mais novo, ajustei as linhas que citavam algunas constantes e pronto. Ficou resolvido, conforme conta na função TBoletoW_Caixa.GerarAutenticacao. Tive de incluir as citadas units na 'uses' ficando assim: uses Classes, SysUtils, ACBrBoletoWS, pcnConversao, pcnGerador, ACBrBoletoConversao, NetEncoding, Hash; É isso. Desculpe se me enganei em algum conceito mas minha intenção é de ajudar. Não sou muito experiente em Delphi para fazer um código mais elaborado. Abaixo anexei os arquivos que modifiquei e que trouxe do Delphi 10.1. Atc, Marcelo. ACBrBoletoW_Caixa.pas ACBrBoletoRet_Caixa.pas System.NetEncoding.pas System.Hash.pas
  25. Olá Jhonlenon, tudo bem? Verifique os campos relativos ao juros de mora. No finalzinho da mensagem de exceção aparece a mensagem abaixo. SERVICO_ENTRADA/DADOS/INCLUI_BOLETO/TITULO/JUROS_MORA/DATA Outra dica é utilizar o boleto de exemplo do ACBR. Me ajudou na implementação. Atc, Marcelo
×
×
  • 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.