Emissão e Controle de Boletos - Componente AcBr no Delphi

Neste pequeno tutorial mostraremos de forma bem simplificada, como utilizar-se do componente AcBrBoleto para realizar o controle de emissão de boletos bancários com base em uma tabela de contas a receber.

Neste artigo falaremos sobre como utilizar o componente AcBr para trabalhar com emissão de boletos. No que sabemos, um dos meios mais utilizados para este controle de emissão de boletos é através do uso de DLL de terceiros, porém depende de licença para uso. Sendo assim, criamos este pequeno tutorial mostrando de forma simples como utilizar o componente AcBrBoleto.

Para exemplificar, criamos um pequeno banco de dados no Firebird 2.5, com apenas três tabelas básicas para o nosso controle. São elas Contas (Listagem 1), Banco (Listagem 2) e Config (Listagem 3).

CREATE SEQUENCE CONTAS_ID; CREATE TABLE CONTAS ( ID INTEGER NOT NULL, NUMCONTA VARCHAR(10), SERIE CHAR(3), DATA_CONTA DATE, DATA_VENC DATE, VALOR_CONTA DOUBLE PRECISION, VALOR_DESCONTO DOUBLE PRECISION, VALOR_ACRESCIMO DOUBLE PRECISION, JUROS DOUBLE PRECISION, MULTA DOUBLE PRECISION, DATA_QUIT DATE, VALOR_QUITATO DOUBLE PRECISION, CLIENTE VARCHAR(50), ENDERECO VARCHAR(50), NUMERO VARCHAR(10), COMPLEMENTO VARCHAR(10), BAIRRO VARCHAR(20), CIDADE VARCHAR(20), CEP VARCHAR(10), UF CHAR(2), CNPJ_CPF VARCHAR(14), INSCRICAO_RG VARCHAR(14), NOSSO_NUMERO VARCHAR(30), BOLETO_IMPRESSO CHAR(3) ); ALTER TABLE CONTAS ADD CONSTRAINT PK_CONTAS PRIMARY KEY (ID);
Listagem 1. Tabela usada para armazenar as contas dos clientes (contas a receber)
CREATE SEQUENCE BANCO_ID; CREATE TABLE BANCO ( ID INTEGER NOT NULL, NUMERO_BANCO VARCHAR(5), DIGITO_NUMERO_BANCO CHAR(1), NOME_BANCO VARCHAR(50), NOME_AGENCIA VARCHAR(50), NUMERO_AGENCIA VARCHAR(10), DIGITO_AGENCIA CHAR(1), NUMERO_CONTA VARCHAR(20), DIGITO_CONTA CHAR(1), CIADE_AGENCIA VARCHAR(20), UF_AGENCIA CHAR(2), NOSSO_NUMERO INTEGER, CEDENTE VARCHAR(50), COD_CEDENTE VARCHAR(20) ); ALTER TABLE BANCO ADD CONSTRAINT PK_BANCO PRIMARY KEY (ID);
Listagem 2. Tabela usada para armazenar os dados bancários da empresa
CREATE SEQUENCE CONFIG_ID; CREATE TABLE CONFIG ( ID INTEGER NOT NULL, PATH_REMESSA VARCHAR(100), PATH_RETORNO VARCHAR(100), PATH_LOGOTIPO VARCHAR(100), PATH_GERARPDF VARCHAR(100), MENSAGEM VARCHAR(250), DIAS_PROTESTO INTEGER, ESPECIE VARCHAR(3), MOEDA VARCHAR(3), ACEITE CHAR(3), CARTEIRA CHAR(3), LOCAL_PAGTO VARCHAR(100), INSTRUCAO_1 VARCHAR(100), INSTRUCAO_2 VARCHAR(100), CONT_REMESSA INTEGER ); ALTER TABLE CONFIG ADD CONSTRAINT PK_CONFIG PRIMARY KEY (ID);
Listagem 3. Tabela usada para armazenar as configurações referentes a boletas

Com estas tabelas criadas no banco de dados, vamos ao projeto. Partindo do ponto de vista que esteja com o componente AcBrBoleto devidamente instalado, abra um novo projeto no Delphi e adicione os componentes de conexão com o banco de dados e respectivos componentes para acessar as tabelas criadas anteriormente. Preferimos trabalhar com os componentes da paleta dbExpress e Data Acess, mas fique a vontade para usar o que lhe parecer melhor.

Adicione também um componente ACBrBoleto1 e um ACBrBoletoFCQuick1. Observe que o AcBr disponibiliza algumas opções para imprimir o boleto. Dentre elas estão os componentes para Rave Report, Fortes Report e Quick Report. No caso usamos o Quick Report, mas para usar qualquer um dos outros, basta ter o componente do tipo instalado e efetivar a ligação com o componente ACBrBoleto1.

Veja como ficou a tela que montada na Figura 1.

Figura 1. Tela montada

No botão direcionado para “Localizar” as contas adicione o código da Listagem 4.

// fecha os componentes de acesso a tabela CdsContas.Close; CdsContas.Params.Clear; SQLContas.Close; SQLContas.SQL.Clear; // passa a SQL para captura das contas em aberto e sem emissão do boleto SQLContas.SQL.Add('select * from contas'); SQLContas.SQL.Add('where contas.data_conta >= :pDatai'); SQLContas.SQL.Add('and contas.data_conta <= :pDataf'); SQLContas.SQL.Add('and contas.boleto_impresso = '+QuotedStr('NAO')); SQLContas.SQL.Add('and contas.data_quit is null'); // passa os paramentos de consulta para os componentes CdsContas.FetchParams; CdsContas.Params.ParamByName('pDatai').AsDate := DataInicio.Date; CdsContas.Params.ParamByName('pDataf').AsDate := DataFim.Date; CdsContas.Open; // se não foram encontrado dados na consulta informa ao usuário if CdsContas.IsEmpty then begin MessageDlg('Não foram encontradas contas no periodo informado!!!', mtInformation, [mbOK], 0); DataInicio.SetFocus; end else DBGrid1.SetFocus;
Listagem 4. Botão localizar contas

O botão indicado para adicionar conta será usado para incluir os dados da conta selecionada numa lista do componente para posteriormente ser gerado o arquivo de remessa para o banco e a impressão dos boletos. O código para isso é mostrado na Listagem 5.

var Titulo : TACBrTitulo; begin if CdsContasNOSSO_NUMERO.IsNull then begin Inc(xNossoNumero); Titulo := ACBrBoleto1.CriarTituloNaLista; with Titulo do begin Vencimento := CdsContasDATA_VENC.AsDateTime; DataDocumento := CdsContasDATA_CONTA.AsDateTime; NumeroDocumento := CdsContasNUMCONTA.AsString; EspecieDoc := CdsConfigESPECIE.AsString; if CdsConfigACEITE.AsString = 'SIM' then Aceite := atSim else Aceite := atNao; DataProcessamento := Now; NossoNumero := IntToStrZero(xNossoNumero,10); Carteira := CdsConfigCARTEIRA.AsString; ValorDocumento := CdsContasVALOR_CONTA.AsFloat; Sacado.NomeSacado := CdsContasCLIENTE.AsString; Sacado.CNPJCPF := CdsContasCNPJ_CPF.AsString; Sacado.Logradouro := CdsContasENDERECO.AsString; Sacado.Numero := CdsContasNUMERO.AsString; Sacado.Bairro := CdsContasBAIRRO.AsString; Sacado.Cidade := CdsContasCIDADE.AsString; Sacado.UF := CdsContasUF.AsString; Sacado.CEP := CdsContasCEP.AsString; ValorAbatimento := 0; LocalPagamento := CdsConfigLOCAL_PAGTO.AsString; ValorMoraJuros := 0; ValorDesconto := 0; ValorAbatimento := 0; DataMoraJuros := 0; DataDesconto := 0; DataAbatimento := 0; DataProtesto := CdsContasDATA_VENC.AsDateTime + CdsConfigDIAS_PROTESTO.AsInteger; PercentualMulta := 0; Mensagem.Text := CdsConfigMENSAGEM.AsString; OcorrenciaOriginal.Tipo := toRemessaBaixar; Instrucao1 := padL(trim(CdsConfigINSTRUCAO_1.AsString),2,'0'); Instrucao2 := padL(trim(CdsConfigINSTRUCAO_2.AsString),2,'0'); Parcela := 1; end; // grava o nosso numero na conta SQLAux.Close; SQLAux.SQL.Clear; SQLAux.SQL.Add('update contas set contas.nosso_numero = :pNossoNum'); SQLAux.SQL.Add('where contas.id = :pIDConta'); SQLAux.Params.ParamByName('pNossoNum').AsInteger := xNossoNumero; SQLAux.Params.ParamByName('pIDCOnta').AsInteger := CdsContasID.AsInteger; SQLAux.ExecSQL(False); // Atualiza a consulta BtnLocalizarClick(Sender); end;
Listagem 5. Opções da conta

Outra rotina importante é a de configuração do componente com os dados necessários. Para isso vamos adicionar no evento OnClick do Combo usado para selecionar o banco em uso para o qual serão emitidos os boletos e adicionar o código da Listagem 6.

xNossoNumero := CdsBancosNOSSO_NUMERO.AsInteger; ConfiguraComponenteAcBr;
Listagem 6. Configuração do componente

Na Listagem 7 temos o código da procedure ConfiguraComponenteAcBr.

procedure TForm1.ConfiguraComponenteAcBr; begin if not CdsConfig.IsEmpty then begin ACBrBoleto1.ACBrBoletoFC.DirLogo := CdsConfigPATH_LOGOTIPO.AsString; ACBrBoleto1.ACBrBoletoFC.Filtro := fiNenhum; ACBrBoleto1.ACBrBoletoFC.LayOut := lPadrao; ACBrBoleto1.Banco.Digito := CdsBancosDIGITO_NUMERO_BANCO.AsInteger; ACBrBoleto1.Banco.Numero := CdsBancosNUMERO_BANCO.AsInteger; ACBrBoleto1.Cedente.Nome := CdsBancosCEDENTE.AsString; ACBrBoleto1.Cedente.CodigoCedente := CdsBancosCOD_CEDENTE.AsString; ACBrBoleto1.Cedente.Agencia := CdsBancosNUMERO_AGENCIA.AsString; ACBrBoleto1.Cedente.AgenciaDigito := CdsBancosDIGITO_AGENCIA.AsString; ACBrBoleto1.Cedente.Conta := CdsBancosNUMERO_CONTA.AsString; ACBrBoleto1.Cedente.ContaDigito := CdsBancosDIGITO_CONTA.AsString; ACBrBoleto1.Cedente.UF := CdsBancosUF_AGENCIA.AsString; ACBrBoleto1.NomeArqRemessa := CdsConfigPATH_REMESSA.AsString+FormatDateTime('DDMMYYYYHHMMSS',Now)+'.TXT';; end; end;
Listagem 7. ConfiguraComponenteAcBr

Agora finalizando o nosso projeto para emissão de boletos vamos apenas inserir os códigos referentes aos botões indicados para imprimir os boletos (Listagem 8), gerar o arquivo de remessa (Listagem 9) e processar arquivo de retorno (Listagem 10).

try ACBrBoleto1.Imprimir; except MessageDlg('Erro ao imprimir os boletos. Verifique!',mtWarning,[mbOK],0); end;
Listagem 8. Imprimir Boletos
var ContadorRemessa : Integer; begin try // captura o contador de remessa e gera a mesma ContadorRemessa := CdsConfigCONT_REMESSA.AsInteger; Inc(ContadorRemessa); ACBrBoleto1.GerarRemessa(ContadorRemessa); // Atualiza a nosso numero no cadastro do banco SQLAux.Close; SQLAux.SQL.Clear; SQLAux.SQL.Add('update banco set banco.nosso_numero = :pNossoNum'); SQLAux.SQL.Add('where banco.id = :pID'); SQLAux.Params.ParamByName('pNossoNum').AsInteger := xNossoNumero; SQLAux.Params.ParamByName('pID').AsInteger := CdsBancosID.AsInteger; SQLAux.ExecSQL(False); // Atualiza o contador de remesa na tabela de configuração SQLAux.Close; SQLAux.SQL.Clear; SQLAux.SQL.Add('update config set config.cont_remessa = :pContador'); SQLAux.SQL.Add('where config.id = :pID'); SQLAux.Params.ParamByName('pContador').AsInteger := ContadorRemessa; SQLAux.Params.ParamByName('pID').AsInteger := CdsConfigID.AsInteger; SQLAux.ExecSQL(False); except MessageDlg('Erro ao gerar arquivo de remessa. Verifique!',mtWarning,[mbOK],0); end;
Listagem 9. Gerar Remessa
var i : Integer; begin if OpenDialog1.Execute then begin //Configurar banco ConfiguraComponenteAcBr; // ACBrBoleto1.NomeArqRetorno := OpenDialog1.FileName; ACBrBoleto1.LerRetorno; for i := 0 to ACBrBoleto1.ListadeBoletos.Count-1 do begin if ACBrBoleto1.ListadeBoletos.Objects[i].ValorRecebido > 0 then begin // Grava a Quitação da conta SQLAux.Close; SQLAux.SQL.Clear; SQLAux.SQL.Add('update contas set'); SQLAux.SQL.Add('contas.data_quit = :pData,'); SQLAux.SQL.Add('contas.valor_quitato = :pValor'); SQLAux.SQL.Add('where contas.nosso_numero = :pNossoNum'); SQLAux.Params.ParamByName('pData').AsDate := ACBrBoleto1.ListadeBoletos.Objects[i].DataBaixa; SQLAux.Params.ParamByName('pValor').AsFloat := ACBrBoleto1.ListadeBoletos.Objects[i].ValorRecebido; SQLAux.Params.ParamByName('pNossoNum').AsInteger := StrToInt(ACBrBoleto1.ListadeBoletos.Objects[i].NossoNumero); SQLAux.ExecSQL(False); end; end; end;
Listagem 10. Processar NomeArqRetorno

Artigos relacionados