/**
* <p>Title: T2Ti ERP</p>
* <p>Description: PAF-ECF + TEF - Classe de controle do TEF.</p>
*
* <p>The MIT License</p>
*
* <p>Copyright: Copyright (C) 2010 T2Ti.COM</p>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* The author may be contacted at:
* t2ti.com@gmail.com</p>
*
* @author Albert Eije (T2Ti.COM)
* @version 1.0
*/
package com.t2tierp.pafecf.infra;
import com.t2tierp.pafecf.view.Caixa;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JOptionPane;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Tef {
//Variáveis de controle
private static String nomeRede, NSU, identificacao, data, hora, valor;
public static boolean relatorioGerencial;
private static boolean transacaoAprovada;
private static Integer contaLinhaEOF;
private static String conteudoArquivo, linhaArquivo, campoArquivo, linha;
//Arquivos de controle
public static File arquivoIntPos001 = new File(System.getProperty("user.dir") + "\\intpos.001");
public static File arquivoImprimeTxt = new File(System.getProperty("user.dir") + "\\imprime.txt");
public static File arquivoTefTxt = new File(System.getProperty("user.dir") + "\\tef.txt");
public static File arquivoPendenteTxt = new File(System.getProperty("user.dir") + "\\pendente.txt");
//Arquivos para comunicação com o GP
public static File reqIntPos001 = new File("c:\\tef_dial\\req\\intpos.001");
public static File respAtivo001 = new File("c:\\tef_dial\\resp\\ativo.001");
public static File respIntPosSts = new File("c:\\tef_dial\\resp\\intpos.sts");
public static File respIntPos001 = new File("c:\\tef_dial\\resp\\intpos.001");
/**
* Realiza a transação TEF.
* @param pIdentificacao identificação da transação
* @param pNumeroCupom número do cupom fiscal - COO
* @param pValorPago valor da transação
* @param pNumeroTransacao número da transação
* @return 0 = GP INATIVO / 1 = OK / -1 = FAIL
*/
public static Integer realizaTransacao(String pIdentificacao, String pNumeroCupom, String pValorPago, Integer pNumeroTransacao) {
Integer result, numeroLinhas;
pValorPago = ajustaValorCartao(pValorPago);
if (respIntPosSts.exists()) {
respIntPosSts.delete();
}
if (respIntPos001.exists()) {
respIntPos001.delete();
}
try {
//Formata arquivo INTPOS.001 para solicitar a transação TEF
conteudoArquivo = "";
conteudoArquivo = "000-000 = CRT" + (char) 13 + (char) 10
+ "001-000 = " + pIdentificacao + (char) 13 + (char) 10
+ "002-000 = " + pNumeroCupom + (char) 13 + (char) 10
+ "003-000 = " + pValorPago + (char) 13 + (char) 10
+ "999-999 = 0";
FileWriter gravar = new FileWriter(arquivoIntPos001);
PrintWriter saida = new PrintWriter(gravar);
saida.println(conteudoArquivo);
saida.close();
gravar.close();
copyFile(arquivoIntPos001, reqIntPos001);
arquivoIntPos001.delete();
} catch (IOException e) {
e.getMessage();
}
if (new File(System.getProperty("user.dir") + "\\imprime" + pNumeroTransacao + ".txt").exists()) {
new File(System.getProperty("user.dir") + "\\imprime" + pNumeroTransacao + ".txt").delete();
}
result = -2;
for (int tentativa = 1; tentativa <= 7; tentativa++) {
try {
// Verifica se o Gerenciador Padrão recebeu o arquivo INTPOS.001
if (respIntPosSts.exists()) {
linhaArquivo = "";
linha = "";
while (result == -2) {
if (respIntPos001.exists()) {
try {
FileReader leitura = new FileReader(respIntPos001);
BufferedReader entrada = new BufferedReader(leitura);
while ((linhaArquivo = entrada.readLine()) != null) {
campoArquivo = linhaArquivo.substring(0, 3);
switch (Integer.parseInt(campoArquivo)) {
case 1: //verifica se o campo de identificação é o mesmo do solicitado
if (!linhaArquivo.substring(10, linhaArquivo.length()).equals(pIdentificacao)) {
entrada.close();
leitura.close();
break;
}
break;
case 9: //verifica se a transação foi aprovada
if (linhaArquivo.substring(10, linhaArquivo.length()).equals("0")) {
transacaoAprovada = true;
result = 1;
}
if (!linhaArquivo.substring(10, linhaArquivo.length()).equals("0")) {
transacaoAprovada = false;
result = -1;
}
break;
case 28: //verifica se existem linhas para serem impressas
if ((Integer.parseInt(linhaArquivo.substring(10, linhaArquivo.length())) != 0) && (transacaoAprovada == true)) {
/*
O arquivo INTPOS.001 é copiado temporariamente. Isso ocorre para cadas transação.
Caso a transação necessite ser cancelada, as informações estarão neste arquivo.
*/
copyFile(respIntPos001, new File("c:\\tef_dial\\resp\\intpos" + pNumeroTransacao + ".001"));
result = 1;
//Armazena o número de linhas para a impressão da via única
numeroLinhas = Integer.parseInt(linhaArquivo.substring(10, linhaArquivo.length()));
//Formata o arquivo para impressão da via única
linha = linha + (char) 13 + (char) 10;
for (int i = 1; i <= numeroLinhas; i++) {
linhaArquivo = entrada.readLine();
if (linhaArquivo.substring(0, 3).equals("029")) {
linha = linha + linhaArquivo.substring(11, linhaArquivo.length() - 1) + (char) 13 + (char) 10;
}
}
linha = linha + (char) 13 + (char) 10 + (char) 13 + (char) 10
+ " . . . . . . . . . . . . . . . . . . . . . . . . "
+ (char) 13 + (char) 10 + (char) 13 + (char) 10;
}
break;
case 30: //Se o campo for 030 exibe uma mensagem para o operador
if (!linha.equals("")) {
JOptionPane.showMessageDialog(null, linhaArquivo.substring(10, linhaArquivo.length()), "Mensagem para o operador", 2);
} else {
while (!respIntPosSts.exists()) {
Thread.sleep(1000);
}
if (reqIntPos001.exists()) {
reqIntPos001.delete();
}
JOptionPane.showMessageDialog(null, linhaArquivo.substring(10, linhaArquivo.length()), "Mensagem para o operador", 2);
result = -1;
}
break;
case 712: //verifica se existem linhas para serem impressas na via do cliente
if ((Integer.parseInt(linhaArquivo.substring(10, linhaArquivo.length())) != 0) && (transacaoAprovada == true)) {
//Armazena o número de linhas para a impressão da via do cliente
numeroLinhas = Integer.parseInt(linhaArquivo.substring(10, linhaArquivo.length()));
//Formata o arquivo para impressão da via do cliente
linha = linha + (char) 13 + (char) 10;
for (int i = 1; i <= numeroLinhas; i++) {
linhaArquivo = entrada.readLine();
if (linhaArquivo.substring(0, 3).equals("713")) {
linha = linha + linhaArquivo.substring(11, linhaArquivo.length() - 1) + (char) 13 + (char) 10;
}
}
linha = linha + (char) 13 + (char) 10 + (char) 13 + (char) 10
+ " . . . . . . . . . . . . . . . . . . . . . . . . "
+ (char) 13 + (char) 10 + (char) 13 + (char) 10;
}
break;
case 714: //Verifica se existem linhas para serem impressas na via do estabelecimento
if ((Integer.parseInt(linhaArquivo.substring(10, linhaArquivo.length())) != 0) && (transacaoAprovada == true)) {
//Armazena o número de linhas para a impressão da via do estabelecimento
numeroLinhas = Integer.parseInt(linhaArquivo.substring(10, linhaArquivo.length()));
//Formata o arquivo para impressão da via do estabelecimento
linha = linha + (char) 13 + (char) 10;
for (int i = 1; i <= numeroLinhas; i++) {
linhaArquivo = entrada.readLine();
if (linhaArquivo.substring(0, 3).equals("715")) {
linha = linha + linhaArquivo.substring(11, linhaArquivo.length() - 1) + (char) 13 + (char) 10;
}
}
linha = linha + (char) 13 + (char) 10 + (char) 13 + (char) 10
+ " . . . . . . . . . . . . . . . . . . . . . . . . "
+ (char) 13 + (char) 10 + (char) 13 + (char) 10;
}
break;
}
if (linhaArquivo == null) { //Chegou no fim do arquivo
break;
}
} //Fim while not EOF
entrada.close();
leitura.close();
} catch (IOException e) {
e.getMessage();
}
} //Fim File exists
} //Fim while result = -2
//Cria o arquivo temporário IMPRIME[transacao].txt com a imagem do comprovante.
if (!linha.equals("")) {
try {
FileWriter gravar = new FileWriter(new File(System.getProperty("user.dir") + "\\imprime" + pNumeroTransacao + ".txt"));
PrintWriter saida = new PrintWriter(gravar);
saida.println(linha);
saida.close();
gravar.close();
break;
} catch (IOException e) {
e.getMessage();
}
}
} //Fim do If RespIntPOS.sts
Thread.sleep(1000);
//Caso o arquivo INTPOS.sts não retorne em 7 segundos exibe mensagem para o operador
if (tentativa == 7) {
if (reqIntPos001.exists()) {
reqIntPos001.delete();
JOptionPane.showMessageDialog(null, "Gerenciador Padrão não está ATIVO!", "Mensagem para o operador", 2);
result = 0;
break;
}
}
if ((result == 0) || (result == -1)) {
break;
}
} catch (InterruptedException ex) {
Logger.getLogger(Tef.class.getName()).log(Level.SEVERE, null, ex);
}
} //Fim do for tentativa
//Se tudo ocorrer bem cria o arquivo PENDENTE.txt
if (result == 1) {
result = 1;
try {
FileWriter gravar = new FileWriter(arquivoPendenteTxt);
PrintWriter saida = new PrintWriter(gravar);
saida.println(pNumeroTransacao);
saida.close();
gravar.close();
} catch (IOException e) {
e.getMessage();
}
}
if (respIntPosSts.exists()) {
respIntPosSts.delete();
}
if (respIntPos001.exists()) {
respIntPos001.delete();
}
return result;
}
/**
* Ajusta o valor para enviar para o GP.
* @param pValor valor do pagamento
* @return valor formatado (Exemplo: 10000 para 100,00
*/
public static String ajustaValorCartao(String pValor) {
String cValorCartao = pValor.substring(0, pValor.indexOf(","))
+ pValor.substring(pValor.indexOf(",") + 1, pValor.length());
return cValorCartao;
}
/**
* Cópia de arquivos por Stream.
* @param pOrigem arquivo de origem.
* @param pDestino arquivo de destino.
* @return nenhum.
*/
public static void copyFile(File pOrigem, File pDestino) throws IOException {
InputStream entradaCopy = new FileInputStream(pOrigem);
OutputStream saidaCopy = new FileOutputStream(pDestino);
// Transfere bytes da entrada para saida
byte[] buf = new byte[1024];
int len;
while ((len = entradaCopy.read(buf)) > 0) {
saidaCopy.write(buf, 0, len);
}
entradaCopy.close();
saidaCopy.close();
}
/**
* Cria uma identificação inicial para a transação.
* @return String com o numero da identificação no formato (HHMMSS)
*/
public static String novaIdentificacao() {
SimpleDateFormat formHora = new SimpleDateFormat("HHmmss");
String identificacao = formHora.format(new Date());
return identificacao;
}
/**
* Verifica se o GP está ativo.
* @return true = Ativo | false = Inativo.
*/
public static boolean verificaGerenciadorPadrao() {
boolean result = false;
if (arquivoIntPos001.exists()) {
arquivoIntPos001.delete();
}
try {
conteudoArquivo = "000-000 = ATV" + (char) 13 + (char) 10
+ "001-000 = " + novaIdentificacao() + (char) 13 + (char) 10
+ "999-999 = 0";
FileWriter gravar = new FileWriter(arquivoIntPos001);
PrintWriter saida = new PrintWriter(gravar);
saida.println(conteudoArquivo);
saida.close();
gravar.close();
copyFile(arquivoIntPos001, reqIntPos001);
arquivoIntPos001.delete();
} catch (IOException e) {
e.getMessage();
}
//tenta sete vezes
for (int tentativa = 1; tentativa <= 7; tentativa++) {
try {
if ((respAtivo001.exists()) || (respIntPosSts.exists())) {
//GP ativo
result = true;
break;
}
Thread.sleep(1000);
if (tentativa == 7) {
result = false;
break;
}
} catch (InterruptedException ex) {
Logger.getLogger(Tef.class.getName()).log(Level.SEVERE, null, ex);
}
}
return result;
}
/**
* Realiza a impressão da Transação TEF.
* @param pFormaPagamento forma de pagamento
* @param pValorPago valor da forma de pagamento
* @param pNumeroCupom número do cupom fiscal - COO
* @param pIdentificacao identificação da transação
* @param pNumeroTransacao número da transação
* @return true ou false
*/
public static boolean imprimeTransacao(String pFormaPagamento, String pValorPago, String pNumeroCupom, String pIdentificacao, Integer pNumeroTransacao) {
boolean result = false;
/*
* Criação do arquivo TEF.TXT. Vamos utilizar esse arquivo caso ocorra
* queda de energia para cancelar a transação.
*/
try {
FileWriter gravar = new FileWriter(arquivoTefTxt);
PrintWriter saida = new PrintWriter(gravar);
saida.println(pNumeroTransacao);
saida.close();
gravar.close();
result = true;
if (new File(System.getProperty("user.dir") + "\\imprime" + pNumeroTransacao + ".txt").exists()) {
//TODO : qual a melhor estratégia para travar o teclado e mouse neste momento?
if (!relatorioGerencial) {
Caixa.ACBrECF.abreCupomVinculado(pNumeroCupom, pFormaPagamento, Double.valueOf(pValorPago));
}
FileReader ler = new FileReader(new File(System.getProperty("user.dir") + "\\imprime" + pNumeroTransacao + ".txt"));
BufferedReader entrada = new BufferedReader(ler);
linha = "";
while ((linha = entrada.readLine()) != null) {
if (!relatorioGerencial) {
Caixa.ACBrECF.linhaCupomVinculado(linha + (char) 13 + (char) 10);
} else {
Caixa.ACBrECF.linhaRelatorioGerencial(linha + (char) 13 + (char) 10, 0);
}
//TODO : Devemos controlar se há erro de comunicação com a impressora? Como?
}
entrada.close();
ler.close();
//TODO : qual a melhor estratégia para destravar o teclado e mouse neste momento?
Caixa.ACBrECF.fechaRelatorio();
}
} catch (IOException e) {
e.getMessage();
} catch (Throwable t) {
JOptionPane.showMessageDialog(null, t.getMessage(), "Erro do Sistema", JOptionPane.ERROR_MESSAGE);
}
return result;
}
/**
* Confirma a Transação TEF.
* @param pNumeroTransacao número da transação
* @return NSU
*/
public static String confirmaTransacao(Integer pNumeroTransacao) {
linhaArquivo = "";
conteudoArquivo = "";
File arquivo;
if (new File("c:\\tef_dial\\resp\\intpos" + pNumeroTransacao + ".001").exists()) {
if (pNumeroTransacao != 0) {
arquivo = new File("c:\\tef_dial\\resp\\intpos" + pNumeroTransacao + ".001");
} else {
arquivo = respIntPos001;
}
try {
FileReader ler = new FileReader(arquivo);
BufferedReader entrada = new BufferedReader(ler);
while ((linhaArquivo = entrada.readLine()) != null) {
if ((linhaArquivo.substring(0, 3).equals("001"))
|| (linhaArquivo.substring(0, 3).equals("002"))
|| (linhaArquivo.substring(0, 3).equals("010"))
|| (linhaArquivo.substring(0, 3).equals("012"))
|| (linhaArquivo.substring(0, 3).equals("027"))) {
conteudoArquivo = conteudoArquivo + linhaArquivo + (char) 13 + (char) 10;
}
if (linhaArquivo.substring(0, 3).equals("999")) {
conteudoArquivo = conteudoArquivo + linhaArquivo;
}
//TODO : Está correta essa forma de pegar o NSU?
if (linhaArquivo.substring(0, 3).equals("012")) {
NSU = linhaArquivo.substring(10, linhaArquivo.length());
}
} //Fim do while not EOF
entrada.close();
ler.close();
// Cria o novo INTPOS.001 da Confirmacão
conteudoArquivo = "000-000 = CNF" + (char) 13 + (char) 10 + conteudoArquivo;
FileWriter gravar = new FileWriter(arquivoIntPos001);
PrintWriter saida = new PrintWriter(gravar);
saida.println(conteudoArquivo);
saida.close();
gravar.close();
copyFile(arquivoIntPos001, reqIntPos001);
arquivoIntPos001.delete();
while (!respIntPosSts.exists()) {
Thread.sleep(1000);
}
respIntPosSts.delete();
return NSU;
} catch (InterruptedException ex) {
Logger.getLogger(Tef.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException e) {
e.getMessage();
}
}
//Exclui o arquivo TEF.txt
if (arquivoTefTxt.exists()) {
arquivoTefTxt.delete();
}
return null;
}
}