terça-feira, 4 de janeiro de 2011

TEF - Realizando uma venda com transação TEF

No artigo passado, iniciamos a nossa primeira comunicação com o Gerenciador Padrão, através de uma função onde era verificado se o mesmo estava ativo, antes de uma transação TEF.
Nesta edição, iremos fazer a nossa primeira venda de cupom fiscal, com pagamento em cartão e realizar a transação TEF.
No código abaixo, estaremos utilizando as funções de impressão do cupom fiscal, tratando o retorno da impressora e realizando a solicitação da transação TEF, com impressão do comprovante. As funções utilizadas, neste código, são:

- Bematech_FI_AbreCupom
- Bematech_FI_VendeItem
- Bematech_FI_IniciaFechamentoCupom
- Bematech_FI_EfetuaFormaPagamento
- Bematech_FI_TerminaFechamentoCupom

Estas funções serão usadas para a impressão do cupom fiscal.

- Bematech_FI_AbreComprovanteNaoFiscalVinculado
- Bematech_FI_UsaComprovanteNaoFiscalVinculado
- Bematech_FI_FechaComprovanteNaoFiscalVinculado

Estas funções serão usadas para a impressão do comprovante da transação TEF.

- Bematech_FI_IniciaModoTEF
- Bematech_FI_FinalizaModoTEF

Estas funções serão usadas para o bloqueio e desbloqueio do teclado e mouse.

Também serão usadas funções extras, definidas como:

- VerificaRetornoFuncaoImpressora
- RealizaTransacao
- ImprimeTransacao

Neste código, estaremos realizando a impressão do cupom fiscal completo com uma transação TEF, mas não estaremos ainda, verificando o tratamento de queda de energia e confirmando a transação.

Estaremos visualizando este código em dois exemplos básicos. Um desenvolvido em Delphi e outro em Visual Basic.

- Exemplo em Delphi

procedure TfrmPrincipal.cmdVendaCupomTEFClick(Sender: TObject);
var cCodigoProduto, cDescricaoProduto, cAliquota, cTipoQtde, cQtde,
   cTipoDesconto, cValorItem, cValorDesconto, cAcrescimoDesconto,    cTipoAcrescimoDesconto, cValorAcrescimoDesconto, cFormaPGTO,
   cMSGPromocional, cValorPago, cNumeroCupom, cSaltaLinha: string;
   iTEF: integer;
   cIdentificacao: TDateTime;
begin
   // Abre Cupom Fiscal, Vende o Item e Fecha Cupom Fiscal.
   iRetorno := Bematech_FI_AbreCupom( pchar( '' ) );
   if ( VerificaRetornoFuncaoImpressora( iRetorno ) ) then
      begin
         cCodigoProduto := '1234567890123';
         cDescricaoProduto := 'Teste de Venda de Item...'; cAliquota := 'II';
         cTipoQtde := 'I'; cQtde := '1'; cValorItem := '1,00';
         cTipoDesconto := '%'; cValorDesconto := '00,00';
         iRetorno := Bematech_FI_VendeItem( pchar( cCodigoProduto ),
            pchar( cDescricaoProduto ), pchar( cAliquota ), pchar( cTipoQtde ),
            pchar( cQtde ), 2, pchar( cValorItem ), pchar( cTipoDesconto ),
            pchar( cValorDesconto ) );
if ( VerificaRetornoFuncaoImpressora( iRetorno ) ) then
            begin
               cAcrescimoDesconto := 'A'; cTipoAcrescimoDesconto := '%';
               cValorAcrescimoDesconto := '00,00';
               iRetorno := Bematech_FI_IniciaFechamentoCupom( pchar(
                  cAcrescimoDesconto ), pchar( cTipoAcrescimoDesconto ),
                  pchar( cValorAcrescimoDesconto ) );
               if ( VerificaRetornoFuncaoImpressora( iRetorno ) ) then
                  begin cFormaPGTO := 'Cartao Credito'; cValorPago := '1,00';
                     SetLength( cNumeroCupom, 6 );
                     iRetorno := Bematech_FI_NumeroCupom( cNumeroCupom );
                     VerificaRetornoFuncaoImpressora( iRetorno );
                     cIdentificacao := Time;
                     iTEF := RealizaTransacao( cIdentificacao, cNumeroCupom,
                        FormatFloat( cValorPago, 0 ) );
                        if ( iTEF = 1 ) then
                           begin
                              iRetorno := Bematech_FI_EfetuaFormaPagamento(
                                 pchar( cFormaPGTO ), pchar( cValorPago ) );
                              if (VerificaRetornoFuncaoImpressora(iRetorno)) then
                                 begin
                                    cMSGPromocional := 'Obrigado, volte
                                                         sempre !!!';
                                    iRetorno :=
                                       Bematech_FI_TerminaFechamentoCupom(
                                       pchar( cMSGPromocional ) );
                                    VerificaRetornoFuncaoImpressora( iRetorno );
                                    ImprimeTransacao( cFormaPGTO, cValorPago,
                                       cNumeroCupom, cIdentificacao );
                                 end;
                           end;
                        if ( iTEF = -1 ) then
                           Application.MessageBox( 'Gerencial Padrão não está
                                                    ativo !',
                              'Atenção', MB_IconError + MB_OK );
                        // Se a transação não for aprovada, deve-se permitir a
                        // escolha de outra forma de pagamento. Neste caso, está
                        // sendo utilizado "Dinheiro" como exemplo.
                        if ( iTEF = -2 ) or ( iTEF = 0 ) then
                           begin
                              cFormaPGTO := 'Dinheiro';
                              iRetorno := Bematech_FI_EfetuaFormaPagamento(pchar(
                                 cFormaPGTO ), pchar( cValorPago ) );
                              if (VerificaRetornoFuncaoImpressora(iRetorno)) then
                                 begin
                                    cMSGPromocional := 'Obrigado, volte
                                                        sempre !!!';
                                    iRetorno :=
                                       Bematech_FI_TerminaFechamentoCupom(
                                       pchar( cMSGPromocional ) );
                                    VerificaRetornoFuncaoImpressora( iRetorno );
                                 end;
                           end;
                  end;
            end;
      end;
end;

//////////////////////////////////////////////////////////
// Função: RealizaTransacao
// Objetivo: Realiza a transação TEF
// Parâmetros: TDateTime para identificar o número da transação
//             string para o Número do Cupom Fiscal (COO)
//             string para a Valor da Forma de Pagamento
// Retorno: True para OK ou False para não OK
////////////////////////////////////////////////////////// function RealizaTransacao( cIdentificacao: TDateTime; cNumeroCupom : string;
   cValorPago: string ): integer;
var cConteudoArquivo, cLinhaArquivo, cLinha: string;
   cArquivo: TextFile; lFlag : longbool; iTentativas, iVezes: integer;
   cMensagem : TForm; bTransacao: boolean;
begin
   if ( FileExists( 'C:\TEF_DIAL\RESP\INTPOS.STS' ) ) then
      DeleteFile( 'C:\TEF_DIAL\RESP\INTPOS.STS' );
   if ( FileExists( 'C:\TEF_DIAL\RESP\INTPOS.001' ) ) then
      DeleteFile( 'C:\TEF_DIAL\RESP\INTPOS.001' );
   AssignFile( cArquivo, 'INTPOS.001');
   // Conteúdo do arquivo INTPOS.001 para solicitar a transação TEF.
   cConteudoArquivo := '';
   cConteudoArquivo := '000-000 = CRT' + #13 + #10 + '001-000 = ' +
      FormatDateTime( 'hhmmss', cIdentificacao ) + #13 + #10 + '002-000 = ' +
      cNumeroCupom + #13 + #10 + '003-000 = ' + cValorPago + #13 + #10 +
      '999-999 = 0';
   ReWrite( cArquivo );
   WriteLn( cArquivo, cConteudoArquivo );
   CloseFile( cArquivo );
CopyFile( pchar( 'INTPOS.001' ), pchar( 'C:\TEF_DIAL\REQ\INTPOS.001' ),
      lFlag );
   DeleteFile( 'INTPOS.001' );
   if FileExists( 'IMPRIME.TXT') then
      DeleteFile( 'IMPRIME.TXT' );
   result := 1;
   for iTentativas := 1 to 7 do
      begin
      // Verifica se o Gerenciador Padrão recebeu o INTPOS.001 da solicitação.
      if ( FileExists( 'C:\TEF_DIAL\RESP\INTPOS.STS' ) ) then
         begin cLinhaArquivo := '';
cLinha := '';
            while True do
               begin
               // Verifica o arquivo INTPOS.001 de resposta.
               if FileExists( 'C:\TEF_DIAL\RESP\INTPOS.001' ) then
                  begin
                     AssignFile( cArquivo, 'C:\TEF_DIAL\RESP\INTPOS.001' );
                     Reset( cArquivo );
while not EOF( cArquivo ) do
                        begin
                           ReadLn( cArquivo, cLinhaArquivo );
                           // Verifica se o campo de identificação é o mesmo
                           // do solicitado.
                           if ( copy( cLinhaArquivo, 1, 3 ) = '001' ) and
                              ( copy( cLinhaArquivo, 11, Length(cLinhaArquivo)
                                 - 10 ) <> FormatDateTime( 'hhmmss',
                                 cIdentificacao ) ) then
                              begin
                                 result := 0;
                                 exit;
                              end;
                           // Verifica se a Transação foi Aprovada.
                           if ( copy( cLinhaArquivo, 1, 3 ) = '009' ) then
                              begin
                                 if ( copy( cLinhaArquivo, 11,
                                    Length( cLinhaArquivo ) - 10 ) ) = '0' then
                                    bTransacao := True;
                                 if ( copy( cLinhaArquivo, 11,
                                    Length( cLinhaArquivo ) - 10 ) ) <> '0' then
bTransacao := False;
                              end;
                           // Verifica se existem linhas para serem impressas.
                           if ( copy( cLinhaArquivo, 1, 3 ) = '028' ) then
                              begin
                                 if ( StrToInt( copy( cLinhaArquivo, 11,
                                    Length( cLinhaArquivo ) - 10 ) ) <> 0 ) and
                                    ( bTransacao = True ) then
                                    begin
                                       result := 1; // OK
                                       for iVezes := 1 to StrToInt( copy(
                                          cLinhaArquivo, 11, Length(
                                          cLinhaArquivo ) - 10 ) ) do
                                          begin
                                             ReadLn( cArquivo, cLinhaArquivo );
                                             // Verifica se o campo é 029 e
                                             // armazena as linhas que serão
                                             // impressas.
                                             if copy( cLinhaArquivo, 1, 3 )
                                                = '029' then
                                                cLinha := cLinha +
                                                copy( cLinhaArquivo, 12,
                                                Length( cLinhaArquivo ) - 12 ) +
                                                #13 + #10;
                                          end;
                                    end;
                              end;
                           // Verifica se o campo é o 030 para mostrar a mensagem
                           // para o operador.
                           if ( copy( cLinhaArquivo, 1, 3 ) = '030' ) and
                              ( cLinha <> '' ) then
                              begin cMensagem := TForm.Create( Nil );
                                 with cMensagem do
                                    begin
                                       with TPanel.Create( Nil ) do
                                          begin
                                             Parent := cMensagem;
                                             Align := alClient;
                                             cMensagem.Font.Size := 15;
                                             Caption := copy( cLinhaArquivo, 11,
                                                Length( cLinhaArquivo ) - 10 );
                                          end;
                                       BorderStyle := bsNone; Height := 129;
                                       Width := 370; Position := poScreenCenter;
                                       Show; Refresh; Sleep( 5000 ); Close;
                                       frmPrincipal.Refresh;
                                    end;
                              end;
                           if ( copy( cLinhaArquivo, 1, 3 ) = '030' ) and
                              ( cLinha = '' ) then
                              begin DeleteFile( 'C:\TEF_DIAL\REQ\INTPOS.001' );
                                 Application.MessageBox( pchar( copy(
                                 cLinhaArquivo, 11, Length( cLinhaArquivo )
                                 - 10 ) ), 'Atenção', MB_IconInformation +
                                 MB_OK );
                                 result := 0;
                              end;
                        end;
                        break;
                     end;
               end;
         // Cria o arquivo temporário IMPRIME.TXT com a imagem do comprovante.
         if ( cLinha <> '' ) then
            begin
               CloseFile( cArquivo );
               AssignFile( cArquivo, 'IMPRIME.TXT' );
               ReWrite( cArquivo );
               WriteLn( cArquivo, cLinha );
               CloseFile( cArquivo );
               Break;
            end;
      end;
      Sleep( 1000 );
      if ( iTentativas = 7 ) then
         begin
            CloseFile( cArquivo ); result := -1;  break;
         end;
      if ( result = 0 ) or ( result = -2 ) then
         begin
            CloseFile( cArquivo ); break;
         end;
      end;
end;

//////////////////////////////////////////////////////////
// Função: ImprimeTransacao
// Objetivo: Realiza a impressão da Transação TEF
// Parâmetros: string para a Forma de Pagamento
//             string para a Valor da Forma de Pagamento
//             string para o Número do Cupom Fiscal (COO)
//             TDateTime para identificar o número da transação
// Retorno: True para OK ou False para não OK ////////////////////////////////////////////////////////// function ImprimeTransacao( cFormaPGTO: string; cValorPago: string; cCOO: string;
   cIdentificacao: TDateTime ): boolean;
var cLinhaArquivo, cLinha, cSaltaLinha, cConteudo: string;
   cMensagem: TForm;
   cArquivo : TextFile;
   iVezes : integer;
begin
   // Bloqueia o teclado e o mouse para a impressão do TEF.
   iRetorno := Bematech_FI_IniciaModoTEF();
   if FileExists( 'IMPRIME.TXT') then
      begin
         iRetorno := Bematech_FI_AbreComprovanteNaoFiscalVinculado( pchar(
            cFormaPGTO ), pchar( cValorPago ), pchar( cCOO ) );
         VerificaRetornoFuncaoImpressora( iRetorno )
      end;
      AssignFile( cArquivo, 'IMPRIME.TXT' );
      begin
         Reset( cArquivo );
         cConteudo := ''; cLinha := '';
         while not EOF( cArquivo ) do
            begin
               ReadLn( cArquivo, cLinha );
               cConteudo := cConteudo + cLinha + #13 + #10;
               iRetorno := Bematech_FI_UsaComprovanteNaoFiscalVinculado( pchar(
                  cLinha ) + #13 );
               VerificaRetornoFuncaoImpressora( iRetorno );
               if EOF( cArquivo ) then
                  begin
                     cSaltaLinha := #13 + #10 + #13 + #10 + #13 + #10 +
                                    #13 + #10 + #13 + #10;
                     iRetorno := Bematech_FI_UsaComprovanteNaoFiscalVinculado(
                        pchar( cSaltaLinha) );
                     VerificaRetornoFuncaoImpressora( iRetorno );
                     cMensagem := TForm.Create( Nil );
                     with cMensagem do
                        begin
                           with TPanel.Create( Nil ) do
                              begin
                                 Parent := cMensagem; Align := alClient;
                                 cMensagem.Font.Size := 15; Caption := 'Por favor,
                                    destaque a 1ª Via';
                              end;
                           BorderStyle := bsNone; Height := 129; Width := 370;
                           Position := poScreenCenter; Show; Refresh;
                           Sleep( 5000 ); Close; frmPrincipal.Refresh;
                        end;
                     iRetorno := Bematech_FI_UsaComprovanteNaoFiscalVinculado(
                        pchar( cConteudo ) );
                     VerificaRetornoFuncaoImpressora( iRetorno );
                  end;
            end;
      end;
   // Desbloqeia o teclado e o mouse.
   iRetorno := Bematech_FI_FinalizaModoTEF();
   CloseFile( cArquivo ); DeleteFile( 'IMPRIME.TXT' );
   iRetorno := Bematech_FI_FechaComprovanteNaoFiscalVinculado();
   VerificaRetornoFuncaoImpressora( iRetorno );
end;

//////////////////////////////////////////////////////////
// Função: VerificaRetornoFuncaoImpressora
// Objetivo: Verificar o retorno da impressora e da função utilizada
// Retorno: True para OK ou False para não OK
////////////////////////////////////////////////////////// function VerificaRetornoFuncaoImpressora( iRetorno: integer ): boolean;
var cMSGErro: string;
begin
   cMSGErro := '';
   result := False;
   case iRetorno of
      0: cMSGErro := 'Erro de Comunicação !';
      -1: cMSGErro := 'Erro de execução na Função !';
      -2: cMSGErro := 'Parâmetro inválido na Função !';
      -3: cMSGErro := 'Alíquota não Programada !';
      -4: cMSGErro := 'Arquivo BEMAFI32.INI não Encontrado !';
      -5: cMSGErro := 'Erro ao abrir a Porta de Comunicação !';
      -6: cMSGErro := 'Impressora Desligada ou Cabo de Comunicação Desconectado!';
      -7: cMSGErro := 'Código do Banco não encontrado no arquivo BEMAFI32.INI !';
      -8: cMSGErro := 'Erro ao criar arquivo STATUS.TXT ou RETORNO.TXT!';
      -27: cMSGErro := 'Status diferente de 6, 0, 0 !';
      -30: cMSGErro := 'Função incompatível com a impressora fiscal YANCO !';
   end;
   if ( cMSGErro <> '' ) then
      begin
         Application.MessageBox( pchar( cMSGErro ), 'Atenção', MB_IconError
            + MB_OK );
         result := False;
      end;
   cMSGErro := '';
   if ( iRetorno = 1 ) then
      begin
         Bematech_FI_RetornoImpressora( iACK, iST1, iST2 );
         if ( iACK = 21 ) then
            begin
               Application.MessageBox( 'A Impressora retornou NAK !' + #13 +
                  'Erro de Protocolo de Comunicação !', 'Atenção', MB_IconError +
                  MB_OK );
               result := False;
            end
         else
         if ( iST1 <> 0 ) or ( iST2 <> 0 ) then
            begin
               // Analisa ST1
               if ( iST1 >= 128 ) then
                  begin
                     iST1 := iST1 - 128;
                     cMSGErro := cMSGErro + 'Fim de Papel' + #13;
                  end;
               if ( iST1 >= 64 ) then
                  begin
                     iST1 := iST1 - 64;
                     cMSGErro := cMSGErro + 'Pouco Papel' + #13;
                  end;
               if ( iST1 >= 32 ) then
                  begin
                     iST1 := iST1 - 32;
                     cMSGErro := cMSGErro + 'Erro no Relógio' + #13;
                  end;
               if ( iST1 >= 16 ) then
                  begin iST1 := iST1 - 16;
                     cMSGErro := cMSGErro + 'Impressora em Erro' + #13;
                  end;
               if ( iST1 >= 8 ) then
                  begin
                     iST1 := iST1 - 8;
                     cMSGErro := cMSGErro + 'Primeiro Dado do Comando não foi ESC'
                        + #13;
                  end;
               if iST1 >= 4 then
                  begin
                     iST1 := iST1 - 4;
                     cMSGErro := cMSGErro + 'Comando Inexistente' + #13;
                  end;
               if iST1 >= 2 then
                  begin
                     iST1 := iST1 - 2;
                     cMSGErro := cMSGErro + 'Cupom Fiscal Aberto' + #13;
                  end;
               if iST1 >= 1 then
                  begin
                     iST1 := iST1 - 1;
                     cMSGErro := cMSGErro + 'Número de Parâmetros Inválidos' + #13;
                  end;
               // Analisa ST2
               if iST2 >= 128 then
                  begin
                     iST2 := iST2 - 128;
                     cMSGErro := cMSGErro + 'Tipo de Parâmetro de Comando Inválido'
                     + #13;
                  end;
               if iST2 >= 64 then
                  begin iST2 := iST2 - 64;
                     cMSGErro := cMSGErro + 'Memória Fiscal Lotada' + #13;
                  end;
               if iST2 >= 32 then
                  begin
                     iST2 := iST2 - 32;
                     cMSGErro := cMSGErro + 'Erro na CMOS' + #13;
                  end;
               if iST2 >= 16 then
                  begin
                     iST2 := iST2 - 16;
                     cMSGErro := cMSGErro + 'Alíquota não Programada' + #13;
                  end;
               if iST2 >= 8 then
                  begin iST2 := iST2 - 8;
                     cMSGErro := cMSGErro + 'Capacidade de Alíquota Programáveis
                        Lotada' + #13;
                  end;
               if iST2 >= 4 then
                  begin
                     iST2 := iST2 - 4;
                     cMSGErro := cMSGErro + 'Cancelamento não permitido' + #13;
                  end;
               if iST2 >= 2 then
                  begin iST2 := iST2 - 2;
                     cMSGErro := cMSGErro + 'CGC/IE do Proprietário não
                        Programados' + #13;
                  end;
               if iST2 >= 1 then
                  begin iST2 := iST2 - 1;
                     cMSGErro := cMSGErro + 'Comando não executado' + #13;
                  end;
               if ( cMSGErro <> '' ) then
                  begin
                     Application.MessageBox( pchar( cMSGErro ), 'Atenção',
                        MB_IconError + MB_OK );
                     result := False;
                  end;
            end
         else
            result := True;
      end;
end;

Nenhum comentário:

Postar um comentário