mlgoncalves
Membros-
Total de ítens
73 -
Registro em
-
Última visita
Tipo de Conteúdo
Blocks
Notes ACBrLibNFe
Fóruns
Downloads
Calendário
Tudo que mlgoncalves postou
-
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
-
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.
-
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
-
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
-
Sergio_api, a unit que postei acima está redondinha. É pegar e usar. Vamos aguardar a revisão para disponibilizarem no repositório. Marcelo.
- 55 replies
-
- 1
-
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
- 55 replies
-
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
- 55 replies
-
Me ajuda numa coisa: onde informo o HOST 'https://auth.sicoob.com.br' que é necessário para a obtenção do token?
- 55 replies
-
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.
- 55 replies
-
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
-
Não consegue ler código de barras do boleto
mlgoncalves replied to mlgoncalves's tópico in ACBrBoleto
Olá ToninhoNunes, Vou verificar agora e retorno aqui. -
Não consegue ler código de barras do boleto
mlgoncalves replied to mlgoncalves's tópico in ACBrBoleto
Bom dia, Antonio Gomes! Obrigado pela atenção. Vou fazer os testes de leitura dos códigos de barra e retorno depois. Atc, Marcelo. -
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.
-
ACBrPagFor - Método GravarTxt() Bando do Brasil
um tópico no fórum postou mlgoncalves Dúvidas Gerais sobre o ACBr
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 -
ACBRPagFor - Método LerTxt()
mlgoncalves replied to mlgoncalves's tópico in Dúvidas Gerais sobre o ACBr
Boa tarde! Segue em anexo unit ACBrPagForLerTxt.pas revisada. Por favor verifiquem e se jugarem pertinentes as alterações favor publicar. Atenciosamente, MarceloACBrPagForLerTxt.rar -
ACBRPagFor - Método LerTxt()
mlgoncalves replied to mlgoncalves's tópico in Dúvidas Gerais sobre o ACBr
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 -
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
-
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
-
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
-
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.
-
Sugestão e ajustes boleto via webservice caixa
mlgoncalves replied to mlgoncalves's tópico in ACBrBoleto
Olá, Segue em anexo a unit alterada. Atc, Marcelo. ACBrBoletoW_Caixa.pas -
Sugestão e ajustes boleto via webservice caixa
mlgoncalves replied to mlgoncalves's tópico in ACBrBoleto
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. -
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
-
Registro de boleto via webservice caixa
mlgoncalves replied to Jhonlenon Ribeiro's tópico in ACBrBoleto
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