Business - Automação Comercial

Automação Comercial com VB, VB.NET e C# (ECF e TEF) - PARTE II de IV

Nesta Segunda Parte desta série de quatro artigos vamos mostrar um pouco sobre o controle de erro no ECF e como fazer TEF de uma forma simples utilizando a DARUMA32.DLL.

por Claudenir Andrade



Nesta Segunda Parte desta série de quatro artigos vamos mostrar um pouco sobre o controle de erro no ECF e como fazer TEF de uma forma simples utilizando a DARUMA32.DLL.

Identificando os Níveis de ERRO

Existem dois níveis de erro que devem ser verificados em sua aplicação de automação comercial quando você estiver desenvolvendo para o ECF. O primeiro deles é o que a função da dll de comunicação com o ECF (que já analisamos no artigo anterior) devolve para seu aplicativo e outro é o que o ECF devolve de erro ou de aviso de um possível erro.

No primeiro nível é fácil o tratamento, pois todas as funções devolvem sempre um valor inteiro que deve ser tratado.

Vamos imaginar que você necessite identificar se o ECF está ligado ou não, neste caso basta chamar a função Daruma_FI_VerificaImpressoraLigada() que esta função irá devolver 0(zero) se estiver desligada e 1(um) se estiver ligada.

Em VB.NET

Private Sub ImpressoraOn_Click_1(
  ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 ... 
RET =  ECFVBNET.Daruma_FI_VerificaImpressoraLigada()
If( RET = 0 ) then
  MessageBox.Show("  ECF DELIGADO")
End If
End Sub

Em C#

private void Cupom_Click(object sender, System.EventArgs e)
{
   ...
  DARUMA32.RET = DARUMA32.Daruma_FI_VerificaImpressoraLigada();
  If ( DARUMA32.RET = 0)
      MessageBox.Show("ECF Desligado");
}

Vale acrescentar que a função daruma_fi_verificaimpressoraligada() deve estar declarado em um módulo genérico ou em um modulo de classe conforme vimos no artigo anterior.

Com o código acima em menos de 7 segundos você irá verificar se o ECF estiver ligado ou não, ou seja, a função verificaimpressoraliogada irá esperar que o ECF responda em 7 segundos, se não responder devolve ZERO para sua variável inteira.

Este exemplo acima ilustra bem o tratamento de um primeiro nível de erro. Porém o uso desta função acima não exige que você entre no segundo nível de tratamento de erro que ;e a decodificação do erro do ecf, isso porque na função acima ( que verifica se o ECF esta ligado ou não) a única necessidade que seu aplicativo tem é analisar se a função devolveu 0(ZERO) ou 1(UM) apenas isso. Porém nas outras funções de envio de comandos para o ECF existe a necessidade de além de decodificar o retorno da função, decodificar também o que o ECF retornou.

Vamos dar o exemplo com a função de fechamento rápido de cupom fiscal, a função Daruma_FI_FechaCupomResumido

Veja o código Abaixo em VB e C#

Em VB

Private Sub Cupom_Click()
Dim Daruma_RET as Integer
Daruma_RET = Daruma_FI_FechaCupomResumido("Dinheiro", "Obrigado Volte Sempre!!")
If( Daruma_RET<> 1) then
  Msgbox(" Erro ao Enviar o Comando para o ECF")
End If
End Sub

Em C#

private void Cupom_Click(object sender, System.EventArgs e)
{
   int DARUMA_RET=0;
   DARUMA_RET = DARUMA32.Daruma_FI_FechaCupomResumido("Cheque","Espero que Funcione");
   If( DARUMA_RET!=1)
      MessageBox.Show("Erro ao Enviar o Comando para o ECF")
   
}

Note que em ambos os casos houve a necessidade de decodificar o ERRO da função, ou seja, não foi necessário entrar na decodificação de ERRO do ECF porque a função já devolveu alguma coisa diferente de 1(um) onde 1(um) significaria que a função conseguiu enviar o comando para o ECF. A tabela de erro da função é uma Tabela Única para todas as funções da dll de comunicação com o ECF, onde 1(UM) significa OK, 0(Zero) Erro de Comunicação, -1(Menos um) parâmetro invalido, etc. Você poderá encontrar a tabela de erro no site www.daruma.com.br baixando o help interativo.

Agora que já sabemos decodificar o ERRO da função e qual seu objetivo, aqui vem uma armadilha. A Função pode devolver 1(um) - indicando que conseguiu enviar o comando para o ECF - porem o ECF pode ter sinalizado um ERRO e seu aplicativo erroneamente identificou que a operação foi OK (porque a função devolveu 1) mas na verdade não foi, porque mesmo a função devolvendo 1(um) - indicando que a comunicação com o ECF foi OK - o ECF pode sinalizar um Erro de por exemplo "Cupom Fiscal Aberto" ou "Alíquota Inexistente" ou "Comando não Executado" e assim por diante.

Sendo assim além de tratar o Erro da Função você deverá chamar uma outra função da DARUAM32.DLL que irá te retornar se o ECF sinalizou erro ou não, veja o código abaixo.

Em VB

Private Sub Cupom_Click()
Dim Daruma_RET as Integer
Dim Daruma_ACK, Daruma_ST1, Daruma_ST2
Daruma_RET = Daruma_FI_FechaCupomResumido("Dinheiro", "Obrigado Volte Sempre!!")
If( Daruma_RET<> 1) then
  Msgbox(" Erro ao Enviar o Comando para o ECF")
End If
Daruma_ACK=0 : Daruma_ST1=0 : Daruma_ST2=0
Daruma_RET = Daruma_FI_RetornoImpressora(Daruma_ACK, Daruma_ST1, Daruma_ST2)
If (Daruma_ACK<>6) 
  MsgBox("Erro de Comunicação com o  ECF")
End if
If (Daruma_ST1<>0) then
  Msgbox("Erro no Status 1 do ECF")
Endif
If (Daruma_ST2<>0) then
  MsgBox) ("Erro no Status 2 do ECF")
End If
End Sub

Em C#

private void Cupom_Click(object sender, System.EventArgs e)
{
   int DARUMA_RET=0;
   int DARUMA_ACK, DARUMA_ST1, DARUMAS_ST2;
   DARUMA_ACK=DARUMA_ST1=DATUMA_ST2=0;
   DARUMA_RET = DARUMA32.Daruma_FI_FechaCupomResumido("Cheque","Espero que Funcione");
   If( DARUMA_RET!=1)
      MessageBox.Show("Erro ao Enviar o Comando para o ECF");
   DARUMA_RET = Daruma_FI_RetornoImpressora(ref ACK, ref ST1, ref ST2);
   If (Daruma_ACK!=6) MessageBox.Show("Erro de comunicacao com o ECF");
   If (Daruma_ST1!=0) MessageBox.Show("Erro no Status 1 do ECF");    
   If (Daruma_ST2!=0) MessageBox.Show("Erro no Status 2 do ECF");
}

Note então que através da DARUMA32.DLL existira a necessidade de ler mais dois Status importantes do ECF, o ST1 e o ST2, onde estarão contidos os erros do ECF, a tabela de erro você poderá encontrar no help interativo conforme figura abaixo:

Um Pequeno Truque da Decodificação de Erro!!

Na Dll Daruma32.dll existe a possibilidade de se fazer um atalho no tratamento de erro. Este atalho irá economizar algumas linhas de processamento que são seriam necessárias caso o ECF esteja OK, ou seja, sem sinalizar ERRO. De mais uma olhada no código fonte acima, que acabamos de digitar. Verifique que nele sempre estaremos chamando a Função Daruma_FI_RetornoImpressora, ou seja, mesmo que a função retorne 1(um) - indicando OK - e que o ECF não esteja sinalizando ERRO, estaremos assim mesmo chamando a função de RetornoImpressora e analisando os bytes de status 1 e status 2. Como evitar isso?

Bem, na DARUMA32.DL, existe a possibilidade de verificar o ERRO do ECF apenas se o mesmo sinalizar um Erro, sendo assim a função Daruma_FI_RetornoImpressora será chamada apenas quando o ST1 e ST2 forem diferentes de 0(ZERO). Mas a questão é... "Como saber se o ST1 e ST2 são diferentes de Zero se só posso saber disso após chamar a função Daruma_FI_RetornoImpressora?" Aqui está o truque:"

Passo 1 - Abre o Registry - Botão Iniciar do Windows - Executar - RegEdit.exe

Passo 2 - Chave HKEY_LOCAL_MACHINE\SOFTWARE\DARUMA\ECF note que dentro da Pasta DARUMA\ECF terá uma chave chamada StatusFuncao coloque esta chave com o Valor 1(um) conforme figura abaixo:

Passo 3 - Feche o Registry e Reinicie.

Existe a possibilidade de se alterar as chaves do Registry da dll também por comandos da dll, sem a necessidade do Usuário ter de Abrir o Registry para configura o ECF, através da Função DARUMA_REGISTRY_STATUSFUNCAO ("1") você altera o valor da Chave para 1. Existe na dll uma função para cada chave do registry existente.

Com esta Chave StatusFuncao igual a 1(um) TODAS as funções da dll irão devolver -27 caso o ECF sinalize erro, assim você irá chamar a função Daruma_FI_RetornoImpressora somente e somente se a função devolver -27, caso contrario continue chamando os comados da dll sem se preocupar com a decodificação de Erro.

Veja agora como fica nossa decodificação de Erro após este truque.

Em VB

Private Sub Cupom_Click()
Dim Daruma_RET as Integer
Dim Daruma_ACK, Daruma_ST1, Daruma_ST2
Daruma_RET = Daruma_FI_FechaCupomResumido("Dinheiro", "Obrigado Volte Sempre!!")
If( Daruma_RET<> 1) then
   Msgbox(" Erro ao Enviar o Comando para o ECF")
End If
If(Daruma_RET <> -27)
 Daruma_ACK=0 : Daruma_ST1=0 : Daruma_ST2=0
 Daruma_RET = Daruma_FI_RetornoImpressora(Daruma_ACK, Daruma_ST1, Daruma_ST2)
 If (Daruma_ACK<>6) 
  MsgBox("Erro de Comunicação com o  ECF")
 End if
 If (Daruma_ST1<>0) then
  Msgbox("Erro no Status 1 do ECF")
 Endif
 If (Daruma_ST2<>0) then
  MsgBox) ("Erro no Status 2 do ECF")
 End If
End If
End Sub

Em C#

private void Cupom_Click(object sender, System.EventArgs e)
{
   int DARUMA_RET=0;
   int DARUMA_ACK, DARUMA_ST1, DARUMAS_ST2;
   DARUMA_ACK=DARUMA_ST1=DATUMA_ST2=0;
   DARUMA_RET = DARUMA32.Daruma_FI_FechaCupomResumido("Cheque","Espero que Funcione");
   If( DARUMA_RET!=1)
      MessageBox.Show("Erro ao Enviar o Comando para o ECF");
   If( DARUMA_RET !=-27)
{
   DARUMA_RET = Daruma_FI_RetornoImpressora(ref ACK, ref ST1, ref ST2);
   If (Daruma_ACK!=6) MessageBox.Show("Erro de comunicacao com o ECF");
   If (Daruma_ST1!=0) MessageBox.Show("Erro no Status 1 do ECF");    
   If (Daruma_ST2!=0) MessageBox.Show("Erro no Status 2 do ECF");
}
}

Observaram a diferença do Código? Ou seja apenas será chamada a função DARUMA_FI_RETORNOIMPRESSORA caso a função devolva -27 ; A função devolverá -27 apenas quando o ECF sinalizar erro, isso pode é perfeitamente possível porque a DLL ela é "Blockante" ou seja ao chamar qualquer função do ECF a DARUMA32.DLL envia o comando para o ECF bloqueando os processos existentes e aguardando a resposta do ECF, com isso ela consegue saber se o ECF sinalizou Erro ou não devolvento para seu aplicativo -27 quando o ECF sinaliza Erro.

Algoritmicamente a DLL se comporta assim:

Passo 1 - Envia o Comando para a DLL
Passo 2 - Fica em um Loop esperando a Resposta do ECF (ST1 e ST2) do comando enviado
Passo 3 - Analisa configuração da DLL, Status função é igual a 1?
Passo 4 - Se for igual a 1(um) e ST1 ou ST2 for diferente de 0(zero) então devolve -27, caso contrario devolve 1(um) porque a função teve sucesso em escrever e ler na serial da impressora.

Sendo assim a forma de como a dll foi construída permite a adoção de truques como o que acima mostramos que sem duvida economiza muito o tratamento de erro do ECF.

No próximo Artigo Explicarmos passo a passo um aplicativo com TEF e como efetuar operações Credito com TEF e finalizaremos o quarto artigo deste curso com o Padrão XML para Automação Comercial.

Claudenir Andrade

Claudenir Andrade - Formado pela Academia de Sistemas Informáticos de Madrid, trabalha com automação comercial há nove anos, foi responsável pela Homologação e aprovação de ECFs brasileiros em países como Equador e Venezuela, gerencia a equipe de desenvolvimento da Daruma Automação. Autor do primeiro livro de automação comercial no Brasil - "Automação Comercial com VB.Net e C#", é também MVP da Microsoft e está criando e definindo o Modelo XML para Automação Comercial, escreve artigos também para o site MSDN e pode ser contatado pelo e-mail - claudenir@daruma.com.br