<?php
/*
  Classe de comunicação com ACBR
*/
// Codigos dos erros na variável nCod_Erro
DEFINE("Acbr_ERRO_Conexao_TCP"       ,  1 );  // Não foi possível conectar na porta TCP ou localizar o Host
DEFINE("Acbr_ERRO_Resposta"          ,  2 );  // ACBR não respondeu
DEFINE("Acbr_ERRO_Versao"            ,  3 );  // Versão do ACBR incompativel
DEFINE("Acbr_ERRO_ECFLinha"          ,  4 );  // Impressora não está em linha
DEFINE("Acbr_ERRO_CNPJ"              ,  5 );  // CNPJ está diferente do ECF
DEFINE("Acbr_ERRO_Desconhecido"      ,  6 );  // Erro desconhecido ( resposta desconhecida)
DEFINE("Acbr_ERRO_Reducao_Z"         ,  7 );  // Impressora precisa tirar Redução Z
DEFINE("Acbr_ERRO_SAT_Inicializacao" , 20 );  // Erro na inicialização do SAT
DEFINE("Acbr_ERRO_SAT_EmissaoCF"     , 21 );  // Erro na emissão do cupom fiscal no SAT
// Codigos dos Tipos de Emssior fiscal      
DEFINE("Acbr_EmissorFiscal_ECF"      ,  0 );  // 0=ECF (Impressora de cupom fiscal)
DEFINE("Acbr_EmissorFiscal_SAT"      ,  1 );  // 1=SAT (Validador de cupom fiscal)
//
CLASS ComACBR {
   // ** Variáveis publicas
   Public  $nTipo_EmissoFiscal;               // Tipo do emissor fiscal
   Public  $Host_IP;                          // IP do Host do ACBR
   Public  $Host_Porta;                       // Porta TCP do ACBR
   Public  $ACBR_Versao;                      // Versão do ACBR    0.9.1 = 0.90001
   Public  $ACBR_DtC;                         // Conectado em DD/MM/AA HH:MM:SS
   Public  $nCod_Erro;                        // Codigo do ERRO
   public  $nCod_Estado_IBGE;                 // Codigo do estado no IBGE, ex: SP=35
   public  $sECF_CNPJ;                        // CNPJ do emitente
   public  $sECF_CNPJ_S;                      // CNPJ do fabricante de software (SoftHouse)
   public  $sSAT_Assinatura;                  // Assinatura eletrônica composta por 344 caracteres
   public  $sECF_CNPJ_E;                      // CNPJ do emissor ECF
   Public  $sACBR_Erro;                       // Mensagem de erro do ACBR
   Public  $sACBR_Resposta;                   // Resposta do ACBR
   Public  $nTempoRcv;                        // Tempo de reposta em Segundos ( 1 = Um segundo, 0.5 = Meio segundo )
   Public  $bVerificarECF;                    // Verificar o ECF ao conectar.
   Public  $nTimeOutECF;                      // Tempo limite de espera de resposta do ECF em segundos
   // ** Variáveis privadas
   Private $PortaTCP;                         // Classe (ClientSocket) do porta TCP cliente para a conexão com o ACBR
   Private $_FimCMD;                          // Fim do comando do ACBR
   //
   //
   public function __construct() {
      $this->nTipo_EmissoFiscal = Acbr_EmissorFiscal_ECF;
	  $this->nCod_Estado_IBGE = 35;
      $this->sECF_CNPJ   = "00.000.000/0000-00";
      $this->sECF_CNPJS  = "00.000.000/0000-00";
	  $this->sSAT_Assinatura = '';
      $this->Host_IP     = "localhost";
      $this->Host_Porta  = 3434;
      $this->PortaTCP = New ClientSocket();
	  $this->PortaTCP->bExceptions = False;
	  $this->_FimCMD     = CHR(13).CHR(10).".".CHR(13).CHR(10);
	  $this->nCod_Erro   = 0;
	  $this->nTempoRcv   = 15;
	  $this->bVerificarECF = True;
	  $this->nTimeOutECF = 60;
	  $this->Desconectar();
	  //
   }
   //
   // Conecta a porta TCP com o ACBR
   Public Function Conectar() {
      $bContinuar = False;
      $this->PortaTCP->open( $this->Host_IP, $this->Host_Porta );
	  If ( $this->bConectado() ) {
	     $sRecebidos = $this->EnvRcv_TCP();
		 // If ( SUBSTR( STRTOUPPER($sRecebidos), 0, 16 )=="ACBRMONITOR VER." ) {  // ACBR antigo
		 //    // Extrair Versão
		 //    $sTMP = SUBSTR($sRecebidos, 17);
		 //    $sTMP = SUBSTR($sTMP, 0, STRPOS($sTMP,CHR(13))-1);
		 //	$sTMP = EXPLODE('.',$sTMP);
		 //	$sTMP[1] = $sTMP[1].STR_REPEAT("0",3-STRLEN($sTMP[1]));
		 //	$sTMP[2] = $sTMP[2].STR_REPEAT("0",3-STRLEN($sTMP[2]));
		 //	$sTMP = $sTMP[0]+($sTMP[1]/1000)+($sTMP[2]/10000000);
		 //	$this->ACBR_Versao = $sTMP+0;
		 //	$bContinuar = True;
		 If ( SUBSTR( STRTOUPPER($sRecebidos), 0, 11 )=="ACBRMONITOR" ) {
		    // Extrair Versão
		    $sTMP = SUBSTR($sRecebidos, STRPOS($sRecebidos,"VER.")+4);
		    $sTMP = SUBSTR($sTMP, 0, STRPOS($sTMP,CHR(13))-1);
			$sTMP = EXPLODE('.',$sTMP);
			$sTMP[1] = $sTMP[1].STR_REPEAT("0",3-STRLEN($sTMP[1]));
			$sTMP[2] = $sTMP[2].STR_REPEAT("0",3-STRLEN($sTMP[2]));
			$sTMP = $sTMP[0]+($sTMP[1]/1000)+($sTMP[2]/10000000);
			$this->ACBR_Versao = $sTMP+0;
			$bContinuar = True;
		 }
		 If ( $bContinuar ) {
			//
			// ** BLOQUEADO PELO ANDRÉ LEANDRO COM A PERMISSÃO DO HAROLDO NO DIA 14/10/2014
			// ** MOTIVO: NOVA VERSÃO 0.10 QUE ESTÁ HAVENDO UM PROBLEMA NESTA VERIFICAÇÃO
	        //If ( $this->ACBR_Versao < 0.8 ) {
		    //   // ERRO(2) versão incompativel
		    //   $this->Desconectar();
			//   $this->nCod_Erro = Acbr_ERRO_Versao;
			//   $bContinuar = False;
			//} Else {
			//   // Conexão aceita
			//   $this->nCod_Erro = 0;
			//}
			// >> Tipo do emissor fiscal: ** ECF **
			If ( $this->nTipo_EmissoFiscal == Acbr_EmissorFiscal_ECF ) {
			   // Não verificar ECF
			   If ( ! $this->bVerificarECF ) {
			      $this->nCod_Erro = 0;
			      Return;
			   }
			   If ( $bContinuar ) {
			      $bContinuar = $this->ECF_SetTimeOut($this->nTimeOutECF);
			   }
			   // ** Ativar ECF
			   If ( $bContinuar ) {
			      If (! $this->ECF_Ativar() ) {
		             // ERRO(3) Impressora não está em linha
		             $this->Desconectar();
			   	     $bContinuar = False;
			         $this->nCod_Erro = Acbr_ERRO_ECFLinha;
			      }
			   }
			   // ** Verificar Estado
			   If ( $bContinuar ) {
			      $nRetornoEst = $this->ECF_Estado();
			      If ($nRetornoEst<0) {
		             // ERRO(5)
		             $this->Desconectar();
			         $this->nCod_Erro = Acbr_ERRO_Desconhecido;
			   	     $bContinuar = False;
			      } ElseIf ($nRetornoEst==8) {
			         // ERRO(18) Impressora precisa tirar Redução Z
			         $this->nCod_Erro = Acbr_ERRO_Reducao_Z;
			      }
			   }
			   // ** Verificar CNPJ
			   If ( $bContinuar ) {
			      $this->sECF_CNPJ_E = $this->ECF_LerCNPJ();
			      $s_V_CNPJ1 = Somente_Numeros($this->sECF_CNPJ_E);
			      $s_V_CNPJ2 = Somente_Numeros($this->sECF_CNPJ);
			      If ( STRLEN($s_V_CNPJ1)<10 OR STRLEN($s_V_CNPJ2)<10 OR $s_V_CNPJ1<>$s_V_CNPJ2 ) {
		             // ERRO(4) CNPJ do ECF é diferente
		             $this->Desconectar();
			         $this->nCod_Erro = Acbr_ERRO_CNPJ;
			   	     $bContinuar = False;
			      }
			   }
			// >> Tipo do emissor fiscal: ** SAT **
			} ElseIf ( $this->nTipo_EmissoFiscal == Acbr_EmissorFiscal_SAT ) {
			   // ** Inicializar SAT
			   If ( $bContinuar ) {
			      If (! $this->SAT_Inicializar() ) {
		             $this->Desconectar();
			   	     $bContinuar = False;
			         $this->nCod_Erro = Acbr_ERRO_SAT_Inicializacao;
			      }
			   }
			   // ** Ativar SAT
			   //If ( $bContinuar ) {
			   //   If (! $this->SAT_Ativar() ) {
		       //      $this->Desconectar();
			   //	     $bContinuar = False;
			   //      $this->nCod_Erro = Acbr_ERRO_SAT_Inicializacao;
			   //   }
			   //}
			   // ** Consulta SAT
			   If ( $bContinuar ) {
			      If (! $this->SAT_ConsultarSAT() ) {
		             $this->Desconectar();
			   	     $bContinuar = False;
			         $this->nCod_Erro = Acbr_ERRO_SAT_Inicializacao;
			      }
			   }
               //
			}
			//
		 } Else {
		    // ERRO(1) ACBR não respondeu
	        $this->nCod_Erro  = Acbr_ERRO_Resposta;
			$this->sACBR_Erro = $sRecebidos;
		    $this->Desconectar();
		 }
	  } Else {
	     // Não foi possivel conectar a porta TCP
	     $this->nCod_Erro = Acbr_ERRO_Conexao_TCP;
	  }
	  Return;
   }
   //
   // Desconecta a porta TCP
   Public Function Desconectar() {
      $this->PortaTCP->close();
	  $this->ACBR_Versao = 0;
	  $this->ACBR_DtC    = '';
	  Return;
   }
   //
   // Verifica se a porta está conectada
   Public Function bConectado() {
      Return ( $this->PortaTCP->bConnected );
   }
   //
   //
   Public Function ECF_LerCNPJ() {
      If (! $this->bConectado() ) { Return False; }
	  $sRecebidos = $this->EnvRcv_TCP("ECF.CNPJ".$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,3)=="OK:" ) {
	     Return SUBSTR($sRecebidos,3);
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return '';
	  }
   }
   //
   // Comando: ECF NumSerie()     Retorna o numero de série do ECF
   Public Function ECF_NumSerie() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.NumSerie'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return SUBSTR($sRecebidos,4);
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return "";
	  }
   }
   //
   // Comando: ECF ModeloECF()     Retorna o modelo ECF
   Public Function ECF_ModeloECF() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.SubModeloECF'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return SUBSTR($sRecebidos,4);
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return "";
	  }
   }
   //
   // Comando: ECF Ativo? (True,False)
   Public Function ECF_Ativo() {
      If (! $this->bConectado() ) { Return False; }
	  $sRecebidos = $this->EnvRcv_TCP("ECF.Ativo".$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,8)=="OK: TRUE" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF Ativar
   Public Function ECF_Ativar() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP("ECF.Ativar".$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF SetTimeOut
   Public Function ECF_SetTimeOut( $nSegundos ) {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP("ECF.SetTimeOut(".$nSegundos.")".$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF Estado    verifica estado da impressora ECF
   Public Function ECF_Estado() {
      If (! $this->bConectado() ) { Return False; }
	  $sRecebidos = $this->EnvRcv_TCP("ECF.Estado".$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     // Impressora não inicializada
	     If ( STRPOS(STRTOUPPER($sRecebidos),"ESTNAOINICIALIZADA")>0 ) {
		    Return 1;
	     // Impressora Livre
	     } ElseIf ( STRPOS(STRTOUPPER($sRecebidos),"ESTLIVRE")>0 ) {
		    Return 3;
	     // Requer redução Z
	     } ElseIf ( STRPOS(STRTOUPPER($sRecebidos),"ESTREQUERZ")>0 ) {
		    Return 8;
		 // Requer Leitura X
	     } ElseIf ( STRPOS(STRTOUPPER($sRecebidos),"ESTREQUERX")>0 ) {
		    Return 9;
		 }
	     Return 0;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return -1;
	  }
   }
   //
   // Comando: ECF Desativar
   Public Function ECF_Desativar() {
      If (! $this->bConectado() ) { Return False; }
      $this->PortaTCP->send("ECF.Desativar".$this->_FimCMD);
	  $sRecebidos = $this->PortaTCP->recv($this->nTempoRcv);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF AbreCupom( CPF ou CNPJ, Nome completo, Endereço )
   Public Function ECF_AbreCupom( $sCPF='', $sNome='', $sEndereco='' ) {
      If (! $this->bConectado() ) { Return False; }
	  $sRecebidos = $this->EnvRcv_TCP('ECF.AbreCupom("'.$sCPF.'","'.$sNome.'","'.$sEndereco.'")'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF FechaCupom( Mensagens )    Ex: Mensagem na linha 1|Mensagem na linnha 2
   Public Function ECF_FechaCupom( $sMensagens='' ) {
      If (! $this->bConectado() ) { Return False; }
	  $sRecebidos = $this->EnvRcv_TCP('ECF.FechaCupom("'.$sMensagens.'")'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF CancelaCupom()   Cancela o cupom atual caso ele esteje aberto ou o ultimo emetido
   Public Function ECF_CancelaCupom() {
      If (! $this->bConectado() ) { Return False; }
	  $sRecebidos = $this->EnvRcv_TCP('ECF.CancelaCupom'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF VendeItem( Codigo do produto, Descrição do produto, ICMS, Quantidade, Valor do produto, Desconto, Unidade )
   Public Function ECF_VendeItem( $sCodigoPro, $sDescricaoPro, $sAliquota_ICMS='0', $sQtdPro='1', $sValorPro='0.001', $sDesconto='0', $sUnidadePro='UN' ) {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.VendeItem("'.$sCodigoPro.    '",'.
	                                                '"'.$sDescricaoPro. '",'.
										            '"'.$sAliquota_ICMS.'",'.
										                $sQtdPro.        ','.
										                $sValorPro.      ','.
										                $sDesconto.      ','.
										            '"'.$sUnidadePro.   '"' .
							')'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF NumCupom()     Retorna o numero do ultimo cupom
   Public Function ECF_NumCupom() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.NumCupom'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return SUBSTR($sRecebidos,4)+0;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return 0;
	  }
   }
   //
   // Comando: ECF SubTotalizaCupom( Valor, Mensagem )
   Public Function ECF_SubTotalizaCupom( $nValor=0, $sMensagem='' ) {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.SubtotalizaCupom('.$nValor.',"'.$sMensagem.'")'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF EfetuaPagamento( Codigo da forma, Valor, Observação, Imprime vinculado )
   Public Function ECF_EfetuaPagamento( $sCodForma, $nValorPag, $sObservacao='', $bImpVinculado=False ) {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.EfetuaPagamento("'.$sCodForma.'",'.$nValorPag.',"'.$sObservacao.'",'.($bImpVinculado ? 'TRUE' : 'FALSE').')'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF CortaPapel()   Corta o papel parcialmente, para equipamentos com guilhotina
   Public Function ECF_CortaPapel() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.CortaPapel'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF LeituraX()   Emitir Leitura X
   Public Function ECF_LeituraX() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.LeituraX'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: ECF ReducaoZ()   Emitir Redução Z
   Public Function ECF_ReducaoZ() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.ReducaoZ'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   //
   Private Function EnvRcv_TCP($sStrBuffer='') {
      If ( STRLEN($sStrBuffer)>0 ) { $this->PortaTCP->send($sStrBuffer); }
	  $sRecebidos = '';
	  $nContador = 0;
	  While ( True ) {
	        $sRecebidos .= $this->PortaTCP->recv(0);
			USLEEP(50000);  // Paralisa por 50 milisegundos
			If ( ($this->nTempoRcv < $nContador*0.05) OR STRPOS($sRecebidos,CHR(3))>0) {
			   $sRecebidos = STR_REPLACE(CHR(3),'',$sRecebidos);
			   BREAK;
			}
			$nContador++;
	  }
      Return $sRecebidos;
   }
   //
   // Comando: ECF AbreGaveta()   Abre a Gaveta de Dinheiro
   Public Function ECF_AbreGaveta() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('ECF.AbreGaveta'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // ** FUNCOES PARA O SAT **
   //
   // Comando: SAT Inicializar()   Inicializa o ACBR para o SAT
   Public Function SAT_Inicializar() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('SAT.Inicializar'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: SAT Inicializar()   Ativar o SAT com o CNPJ e codigo do estado
   Public Function SAT_Ativar() {
      If (! $this->bConectado() ) { Return False; }
	  $sCNPJ = Somente_Numeros($this->sECF_CNPJ);
      $sRecebidos = $this->EnvRcv_TCP('SAT.Ativar("'.$sCNPJ.'",'.$this->nCod_Estado_IBGE.')'.$this->_FimCMD);
      $this->sACBR_Resposta = SUBSTR($sRecebidos,STRPOS(STRTOUPPER($sRecebidos),"OK: ")+5);
	  $aResposta = EXPLODE("|",$this->sACBR_Resposta);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" && ( (@$aResposta[1]+0)==4000 Or (@$aResposta[1]+0)==4003 ) ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: SAT AssociarAssinatura
   Public Function SAT_AssociarAssinatura() {
      If (! $this->bConectado() ) { Return False; }
	  $sCNPJs = Somente_Numeros($this->sECF_CNPJ.$this->sECF_CNPJ_S);
      $sRecebidos = $this->EnvRcv_TCP('SAT.AssociarAssinatura("'.$sCNPJs.'","'.$this->sSAT_Assinatura.'")'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" && STRPOS(STRTOUPPER($sRecebidos),"ERRO")==0 ) {
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $sRecebidos;
	     Return False;
	  }
   }
   //
   // Comando: SAT CriarEnviarCfe
   Public Function SAT_CriarEnviarCfe($sInf_CfePrm) {
      If (! $this->bConectado() ) { Return False; }
      $sInf_CfeTxt = $sInf_CfePrm;
	  $sInf_CfeTxt = STR_REPLACE("{CNPJ-SOFTHOUSE}"   ,Somente_Numeros($this->sECF_CNPJ_S), $sInf_CfeTxt);              // CNPJ da Softhouse
	  $sInf_CfeTxt = STR_REPLACE("{CNPJ-EMITENTE}"    ,Somente_Numeros($this->sECF_CNPJ)  , $sInf_CfeTxt);              // CNPJ do emitente
	  $sInf_CfeTxt = STR_REPLACE("{ASSINATURA-PADRAO}",$this->sSAT_Assinatura             , $sInf_CfeTxt);              // Assinatura digital SAT
      $sRecebidos = $this->EnvRcv_TCP('SAT.CriarEnviarCfe("'.$sInf_CfeTxt.'")'.$this->_FimCMD);
	  $this->sACBR_Resposta = '';
	  If ( STRPOS(STRTOUPPER($sRecebidos),"RESULTADO=")>0 ) {
	     $this->sACBR_Resposta = SUBSTR($sRecebidos,STRPOS(STRTOUPPER($sRecebidos),"RESULTADO=")+11);
	  }
	  $aResposta = EXPLODE("|",$this->sACBR_Resposta);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" && STRPOS(STRTOUPPER($sRecebidos),"ERRO")==0 && (@$aResposta[1]+0)==6000 ) {
	     $this->sACBR_Erro = 0;
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $aResposta[3];
		 $this->nCod_Erro = Acbr_ERRO_SAT_EmissaoCF;
	     Return False;
	  }
   }
   //
   // Comando SAT ImprimirExtratoVenda
   Public Function SAT_ImprimirExtratoVenda($sCaminhoDoXML) {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('SAT.ImprimirExtratoVenda("'.$sCaminhoDoXML.'")'.$this->_FimCMD);
	  $this->sACBR_Resposta = '';
	  If ( STRPOS(STRTOUPPER($sRecebidos),"RESULTADO=")>0 ) {
	     $this->sACBR_Resposta = SUBSTR($sRecebidos,STRPOS(STRTOUPPER($sRecebidos),"RESULTADO=")+11);
	  }
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" && STRPOS(STRTOUPPER($sRecebidos),"ERRO")==0) {
	     Return True;
	  } Else {
	     Return False;
	  }
   }
   //
   // Comando SAT CancelarCFe
   Public Function SAT_CancelarCFe($sChaveCFe,$sCaminhoDoXML) {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('SAT.CancelarCFe("'.$sChaveCFe.'","'.$sCaminhoDoXML.'")'.$this->_FimCMD);
	  $this->sACBR_Resposta = '';
	  If ( STRPOS(STRTOUPPER($sRecebidos),"RESULTADO=")>0 ) {
	     $this->sACBR_Resposta = SUBSTR($sRecebidos,STRPOS(STRTOUPPER($sRecebidos),"RESULTADO=")+11);
	  }
	  $aResposta = EXPLODE("|",$this->sACBR_Resposta);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" && STRPOS(STRTOUPPER($sRecebidos),"ERRO")==0 && (@$aResposta[1]+0)==7000 ) {
	     $this->sACBR_Erro = 0;
	     Return True;
	  } Else {
	     $this->sACBR_Erro = $aResposta[3];
		 $this->nCod_Erro = Acbr_ERRO_SAT_EmissaoCF;
	     Return False;
	  }
   }
   // Comando SAT ImprimirExtratoCancelamento
   Public Function SAT_ImprimirExtratoCancelamento($sCaminhoDoXML) {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('SAT.ImprimirExtratoCancelamento("'.$sCaminhoDoXML.'")'.$this->_FimCMD);
	  $this->sACBR_Resposta = '';
	  If ( STRPOS(STRTOUPPER($sRecebidos),"RESULTADO=")>0 ) {
	     $this->sACBR_Resposta = SUBSTR($sRecebidos,STRPOS(STRTOUPPER($sRecebidos),"RESULTADO=")+11);
	  }
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" && STRPOS(STRTOUPPER($sRecebidos),"ERRO")==0) {
	     Return True;
	  } Else {
	     Return False;
	  }
   }
   //
   // Comando SAT ConsultarSAT
   Public Function SAT_ConsultarSAT() {
      If (! $this->bConectado() ) { Return False; }
      $sRecebidos = $this->EnvRcv_TCP('SAT.ConsultarSAT()'.$this->_FimCMD);
      If ( SUBSTR(STRTOUPPER($sRecebidos),0,2)=="OK" && STRPOS(STRTOUPPER($sRecebidos),"ERRO")==0) {
	     $this->sACBR_Resposta = SUBSTR($sRecebidos,STRPOS(STRTOUPPER($sRecebidos),"OK: ")+5);
	     $aResposta = EXPLODE("|",$this->sACBR_Resposta);
	     Return (@$aResposta[1]+0);
	  } Else {
	     Return False;
	  }
   }
}

?>
