<?php

class DadosST{
    public $EmpresaID  = 0;
	public $CadastroID = 0;  
	public $produtos = array();
	
	public function addProdutos($produtoClass){
	  array_push($this->produtos, $produtoClass);	
	}	
	
	public function getProducts(){	
	  return $this->produtos;
	}
}

class Produto{
    public $ProdutoId      = 0;
	public $quantidade     = 0;  
	public $ValorUnitario  = 0;
	public $AcrescimoPerc  = 0; 
	public $AcrescimoValor = 0;
	public $DescontoPerc   = 0;
	public $SeguroValor    = 0;
	public $FreteValor     = 0;
}



class Futuracalcularst{

  private $registry;

  public function __construct($registry) {
	
  }
  
  public function loadInstances($registry){
	$this->config   = $registry->get('config');
	$this->db       = $registry->get('db');
	$this->request  = $registry->get('request');
	$this->session  = $registry->get('session');  
	$this->cart     = $registry->get('cart');
	$this->tax      = $registry->get('tax');
	$this->registry = $registry;
	
	if(!isset($this->session->data['histcalculost'])){
		$this->session->data['histcalculost'] = new DadosST();
	}
	
	if(!isset($this->session->data['ultimocalculost'])){
		$this->session->data['ultimocalculost'] = false;
	}
	
	if(!isset($this->session->data['ultimaconsultarest'])){
		$this->session->data['ultimaconsultarest'] = 0;
	}
	
	if(!isset($this->session->data['IDSession'])){
	    $this->session->data['IDSession'] = null;
	}
	
  }
  
  public function __get($name) {
	return $this->registry->get($name);
  }  
  
  public function getSubTotal($produtos) {
	$total = 0;
		
	foreach ($produtos as $product) {
		$total += $product['total'];
	}
	return $total;
  }
   
   public function getDesconto(){
		// Totals		
		$this->load->model('setting/extension');			
		
		$total_data = array();					
		$total = 0;	
		$retorno = 0;

		$taxes = $this->cart->getTaxes();
		
		// Display prices
		if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {			
			$results = $this->model_setting_extension->getExtensions('total');

			foreach ($results as $result) {
				if ($this->config->get($result['code'] . '_status')) {				
					$this->load->model('total/' . $result['code']);
					
			        $this->{'model_total_' . $result['code']}->getTotal($total_data, $total, $taxes);	
				}
			
			}
			
			foreach($total_data as $data){
			
			  if ($data['value'] < 0){
				$retorno += $data['value'];
			  }
			
			}
		}  
		
        return $retorno * -1;	  
   }
   
   private function recalculaImpostos(DadosST $ultimoCalculo, DadosST $atual){
     $prodold   = $ultimoCalculo->produtos;
	 $prodatual = $atual->produtos;
	 
	 
     if(sizeof($prodold) != sizeof($prodatual)){
	   return true;
	 }
	 
	 if(($ultimoCalculo->EmpresaID != $atual->EmpresaID) || ($ultimoCalculo->CadastroID != $atual->CadastroID)){
	    return true;
	 }
	 
	 $produtosOld  = $ultimoCalculo->produtos;
	 $produtoAtual = $atual->produtos;
 
	 $x = 0;
     foreach($produtosOld as $produtoOld){	 
		if(
		    ($produtoOld->ProdutoId      != $produtoAtual[$x]->ProdutoId)      ||
			($produtoOld->quantidade     != $produtoAtual[$x]->quantidade)     ||
			($produtoOld->ValorUnitario  != $produtoAtual[$x]->ValorUnitario)  ||
			($produtoOld->AcrescimoPerc  != $produtoAtual[$x]->AcrescimoPerc)  ||
			($produtoOld->AcrescimoValor != $produtoAtual[$x]->AcrescimoValor) ||
			($produtoOld->DescontoPerc   != $produtoAtual[$x]->DescontoPerc)   ||
			($produtoOld->SeguroValor    != $produtoAtual[$x]->SeguroValor)    ||
			($produtoOld->FreteValor     != $produtoAtual[$x]->FreteValor) 
		  ){return true;};
		  
		$x ++;
	 } 	 
	 
	 return false;
   }   
   
   private function getJsonInput($produtos, $clienteid, $totaldesconto){ 
    
    $query = $this->db->query("select value from " . DB_PREFIX . "setting s where (s.key = 'futuracalcularst_usuario') and (s.group = 'futuracalcularst')");
	
	if(!($query->num_rows)){
      $this->session->data['ultimocalculost'] = false;	
	  return false;
	}	
	$empresaid = $query->row['value'];
	
	$dadosst             = new DadosST();	
	$dadosst->CadastroID = $clienteid;
	$dadosst->EmpresaID  = $empresaid;
	
	if(isset($this->session->data['shipping_method']['cost'])){
		$totalfrete = $this->session->data['shipping_method']['cost'];
	}else{
	  $this->session->data['ultimocalculost'] = false;
	  return false;	
	}
	 
	$subtotal = $this->getSubTotal($produtos);
	
	foreach($produtos as $produto){		
	  $classProduto = new Produto();	  
	  $baseproduto  = (($produto['quantity'] * $produto['price']) * 100) / $subtotal;

	  $classProduto->ProdutoId       = $produto['id_futura'];
	  $classProduto->quantidade      = $produto['quantity'];
	  $classProduto->ValorUnitario   = $produto['price'];
	  $classProduto->AcrescimoPerc   = 0;
	  $classProduto->AcrescimoValor  = 0;
	  
	  $valorDescProd                 = ($baseproduto  / 100) * $totaldesconto;
	  
	  $classProduto->DescontoPerc    = ($valorDescProd * 100) / $subtotal;	
  	  
	  $classProduto->SeguroValor     = 0;
	  
	  $classProduto->FreteValor      = ($baseproduto / 100) * $totalfrete;
	  
	  $dadosst->addProdutos($classProduto);
	}	

    
	$recalcular = $this->recalculaImpostos($this->session->data['histcalculost'], $dadosst);
	
    $this->session->data['histcalculost'] = $dadosst;	
	
	//se n�o teve mudan�a, nao recalcula os valores....
	if(($recalcular) || (!$this->session->data['ultimocalculost'])){
	  $this->session->data['ultimocalculost'] = false;
	  return $dadosst;	  
	}else{	  
	  return false;		
	}	
  }  
  
  public function getconfiguracoes(){
    $result = array();
	
	$query = $this->db->query("select s.value, s.key from " . DB_PREFIX . "setting s where (s.group = 'futuracalcularst') and ((s.key = 'futuracalcularst_status') or (s.key = 'futuracalcularst_user') or (s.key = 'futuracalcularst_senha') or (s.key = 'futuracalcularst_ip') or (s.key = 'futuracalcularst_porta') or (s.key = 'futuracalcularst_id_empresa')) ");
	
	foreach($query->rows as $data){	
      $result[$data['key']] = $data['value'];		
	}  	
	return $result;	
  }
  
  private function get_headers_from_curl_response($headerContent)
  {  
	$headers = array();
	$arrRequests = explode("\r\n\r\n", $headerContent);

	for ($index = 0; $index < count($arrRequests) -1; $index++) {

		foreach (explode("\r\n", $arrRequests[$index]) as $i => $line)
		{
			if ($i === 0)
				$headers[$index]['http_code'] = $line;
			else
			{
				list ($key, $value) = explode(': ', $line);
				$headers[$index][$key] = $value;
			}
		}
	}

	return $headers;
  }  
  
  
  public function getWebServerCalculoST($jsoninput){
      
      //pega configuracoes no model
      $confs = $this->getconfiguracoes();
      
      $user  = $confs['futuracalcularst_user'];
      $senha = $confs['futuracalcularst_senha'];
      
      $ch = curl_init();
      
      if (!isset($this->session->data['IDSession'])){
        curl_setopt($ch, CURLOPT_HTTPHEADER, array ( "Accept: application/json", "Content-Type: text/plain; charset=utf-8" ) ) ;
      }else{
    	curl_setopt($ch, CURLOPT_HTTPHEADER, array ( "Accept: application/json", "Content-Type: text/plain; charset=utf-8", "Pragma: dssession=" . $this->session->data['IDSession'] ) ) ;	    
      }
      
      curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
      curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $senha);
      curl_setopt($ch, CURLOPT_HEADER, true ) ;
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true ) ;
      curl_setopt($ch, CURLOPT_POST, TRUE ) ;
      curl_setopt($ch, CURLOPT_URL, "http://" . $confs['futuracalcularst_ip'] . ":" . $confs['futuracalcularst_porta'] . "/datasnap/rest/TfOtr_ServerMethodsUnit/%22CalculaST%22/") ;
      curl_setopt($ch, CURLOPT_POSTFIELDS, $jsoninput);
      $result = curl_exec($ch);
      
      if(!$result){
          $this->session->data['ultimaconsultarest'] = time();
          return false;
      }
      
      //Separando header e retorno
      $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
      $header = substr($result, 0, $header_size);
      $json = substr($result, $header_size, strlen($result) - strlen($header_size));
      //transformando o header em array
      
      $arrayHeader = null;
    	
      if($header != ''){
        $lista = $this->get_headers_from_curl_response($header);
    
    	for($i = 0; $i < sizeOf($lista); $i++){
    	   if(array_key_exists("Pragma", $lista[$i])){
    	       $arrayHeader = $lista[$i];
    		   break;
    		}			
    	}
    	
        }else {
    	  $this->session->data['ultimaconsultarest'] = time();
    	  return false;	
    	}
      
      //capturando apenas sessao dsession do retorno
      $dsession = "";
      if(isset($arrayHeader["Pragma"])){
          $dsession = substr($arrayHeader["Pragma"], 10, strpos($arrayHeader["Pragma"], ',')-10);
      }
      
      curl_close($ch);  
      
      return $json;
  }
  
  public function finalizaUltimaSessao(){
  
      if(!isset($this->session->data['IDSession'])){
          return;
      }
  
      $confs = $this->getconfiguracoes();
  
      $user  = $confs['futuracalcularst_user'];
      $senha = $confs['futuracalcularst_senha'];
  
      try{
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_HTTPHEADER, array ( "Accept: application/json", "Content-Type: text/plain; charset=utf-8", "Pragma: dssession=" . $this->session->data['IDSession'] ) ) ;
          curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
          curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $senha);
          curl_setopt($ch, CURLOPT_HEADER, true ) ;
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true ) ;
          curl_setopt($ch, CURLOPT_POST, FALSE ) ;
          curl_setopt($ch, CURLOPT_URL, "http://" . $confs['futuracalcularst_ip'] . ":" . $confs['futuracalcularst_porta'] . "/datasnap/rest/TfOtr_ServerMethodsUnit/%22CloseSession%22/") ;
          $resultado=curl_exec($ch);
          curl_close($ch);
      }catch(Exception $e){
      }
  
      $this->session->data['IDSession'] = null;
  
  }
  
  function getSTFromArray($pProdutoFutura, $array){
       
      if (!is_array($array))
          return 'N';
  
  
          foreach($array as $arrayitens){
  
  
              $jsonArray = json_decode($arrayitens, true);
  
              if (!$jsonArray){
                  return 'N';
              }
              	
              if((array_key_exists('result', $jsonArray)) && (array_key_exists(0, $jsonArray['result'])) && (array_key_exists('Produtos', $jsonArray['result'][0]))){
                  $produtosLista = $jsonArray['result'][0]['Produtos'];
              }	else{
                  return 'N';
              }
  
              for($i = 0; $i <= sizeOf($produtosLista) - 1; $i ++){
                  if (strcmp($produtosLista[$i]["ProdutoId"], $pProdutoFutura) == 0){
                      return $produtosLista[$i]["SubstTribValor"];
                  }
              }
  
          }
           
          return 'N';
  
  }
  
  function getIPIFromArray($pProdutoFutura, $array){
      if (!is_array($array))
          return 'N';
           
          foreach($array as $arrayitens){
  
  
              $jsonArray = json_decode($arrayitens, true);
  
              if (!$jsonArray){
                  return 'N';
              }
  
              if((array_key_exists('result', $jsonArray)) && (array_key_exists(0, $jsonArray['result'])) && (array_key_exists('Produtos', $jsonArray['result'][0]))){
                  $produtosLista = $jsonArray['result'][0]['Produtos'];
              }	else{
                  return 'N';
              }
  
              for($i = 0; $i <= sizeOf($produtosLista) -1; $i ++){
                   
                  if (strcmp($produtosLista[$i]["ProdutoId"], $pProdutoFutura) == 0){
                      return $produtosLista[$i]["IPIValor"];
                  }
                  	
              }
  
          }
  
          return 'N';
           
  }

  
  public function getJsonCalculaST($produtos, $cliente, $totaldesconto){ 
	if(!$produtos){
	  return false;
	}
  
	$vatual = time();

	//Captura JSON no model
    $jsoninput = $this->getJsonInput($produtos, $cliente, $totaldesconto);		

	
	if((($vatual - $this->session->data['ultimaconsultarest']) <= 20) && (!$this->session->data['ultimocalculost']) && ($this->session->data['ultimaconsultarest'] != 0)){
	  return false;
	}	
	
	if($this->session->data['ultimocalculost'] && (!$jsoninput)){
	  return $this->session->data['ultimocalculost']; 
	}
	
	if((!$this->session->data['ultimocalculost'])  && (!$jsoninput)){
	  return false;	
	}

	//Consumindo WEBSERVICE em partes de 100 itens cada... ByMatheus
	$prodsAux = $jsoninput->produtos;
	
	$json = array();
	$listjsonCount = 0;
	$countAdd = -1;
	
	while(sizeof($prodsAux) > 0){		
		$tmpDadosst             = new DadosST();	
		$tmpDadosst->CadastroID = $jsoninput->CadastroID;
		$tmpDadosst->EmpresaID  = $jsoninput->EmpresaID;		
		
        $produtosTemp = array();
		for ($count = 0; $count <= 100; $count++){
            if(sizeof($prodsAux) > 0){ 	
			    $countAdd ++;			
				array_push($produtosTemp, $prodsAux[$countAdd]);
				unset($prodsAux[$countAdd]);						
			}else{
				break;
			}
		}
		
		$tmpDadosst->produtos = $produtosTemp; 
		
		$jsonTemp = json_encode($tmpDadosst);
		

		$jsonretorno = $this->getWebServerCalculoST($jsonTemp);
		
		$jsonconv = json_decode($jsonretorno, true);
		
		if((!isset($jsonconv)) || (array_key_exists('error',$jsonconv))){
		    $this->finalizaUltimaSessao();
			return false;	
		}
		
		$listjsonCount ++;		
	
        array_push($json, $jsonretorno);
	}
	
	 $this->finalizaUltimaSessao();


	
	$this->session->data['ultimocalculost'] = $json;
	
    return $json;   
  }
  
  public function jsonencode($json){
    return json_encode($json); 
  }

} 

?>