<?php
class ControllerPaymentCieloTransparente extends Controller {
  private $error = array();

  private function juroComposto($capital, $tempo, $juros, $tipo = 0) {
    $juros = !empty($juros) ? preg_replace('/[^0-9\s]+/', '.', $juros) : 0;
    settype($juros, 'float');

    $m = $capital * pow((1 + ($juros / 100)), $tempo);

    if ($tipo == 0) {
      return $m;
    } else {
      return ($m / $tempo);
    }
  }

  public function index() {
    $this->app();

    $language = $this->language->load('payment/cielo_transparente');
		$this->data = array_merge($this->data, $language);

    $this->data['idboleto']              = base64_encode($this->session->data['order_id']);
    $this->data['back']                  = $this->url->link('checkout/checkout', '', 'SSL');
    $this->data['continue']              = $this->url->link('checkout/success');
    $this->id                            = 'payment';

    if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/cielo_transparente.tpl')) {
      $this->template = $this->config->get('config_template') . '/template/payment/cielo_transparente.tpl';
    } else {
      $this->template = 'default/template/payment/cielo_transparente.tpl';
    }

    $this->data['cielo_transparente_master']         = $this->config->get('cielo_transparente_master');
    $this->data['cielo_transparente_visa']           = $this->config->get('cielo_transparente_visa');
    $this->data['cielo_transparente_amex']           = $this->config->get('cielo_transparente_amex');
    $this->data['cielo_transparente_diners']         = $this->config->get('cielo_transparente_diners');
    $this->data['cielo_transparente_elo']            = $this->config->get('cielo_transparente_elo');
    $this->data['cielo_transparente_discover']       = $this->config->get('cielo_transparente_discover');
    $this->data['cielo_transparente_parcela_qtdmax'] = $this->config->get('cielo_transparente_parcela_qtdmax');


    $this->session->data['cielo_retentativa'] = 0; //controla a quantidade de tentativas caso o retorno da cielo seja 06 ou 96

    $this->response->setOutput($this->render('payment/cielo_transparente'));


  }

  public function callback() {

    $json = array();
    $this->load->language('payment/cielo_transparente');

    if ($this->validate()){
      ini_set("allow_url_fopen", 1);

      $order_id = base64_decode($this->session->data['order_id']);

      $this->load->dmodel('checkout/order');
      $this->load->model('payment/cielo_transparente');

      $cieloidpedido = $order_id;

      $cieloorderID  = $this->model_payment_cielo_transparente->getOrderCieloID($cieloidpedido);
      if (!$cieloorderID){//validação para não deixar duplicar o pagamento
        function cartaocreditoADS($string)
        {
          $string = str_replace('+','',$string);
          $string = str_replace(' ','',$string);
          return $string;
        }

        function TidADS($string)
        {
          $string = str_replace('<br/>','',$string);
          return $string;
        }

        $cartaocredito = cartaocreditoADS($this->request->post['creditcard_ccno']);
        $csv           = $this->request->post['creditcard_cccvd'];
        $nome_titular  = $this->request->post['creditcard_name'];
        $validade      = preg_replace('/([^0-9])/i','', $this->request->post['expire']);
        $validade = substr($validade, -4).substr($validade, 0,2);
        $formapagamento = $this->request->post['formaPagamento'];
        $parte          = explode("|", $formapagamento);
        $parcelas       = $parte[0];
        $valor          = $parte[1];
        $vvalorcielo    = number_format($valor * $parcelas,2,'.','');
        $compratotal    = number_format($vvalorcielo,2,'','');
        $bandeira       = $this->request->post['creditcard_cctype'];
        $nome_titular   = $this->request->post['creditcard_name'];
        $tipocartao     = 'CC';
        $dominios       = $_SERVER['HTTP_HOST'];
        $urlretorno     = "http://$dominios/";
        $cielo_numero   = $this->config->get('cielo_transparente_numero');
        $cielo_chave    = $this->config->get('cielo_transparente_chave');
        $pedidoloja     = $this->session->data['order_id'];
        // Verifica Cart&atilde;o Digitado
        if($cartaocredito <> '') {


          $formataurl = $this->config->get('cielo_transparente_url_site');

          $site_url = $formataurl."/system/library/wbcielo.php";
          $ch = curl_init();
          $timeout = 10; // set to zero for no timeout
          curl_setopt ($ch, CURLOPT_URL, $site_url);
          curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
          curl_setopt($ch, CURLOPT_POSTFIELDS,"cc=$cartaocredito&bandeira=$bandeira&validade=$validade&csv=$csv&nome_titular=$nome_titular&pedidoloja=$pedidoloja&compratotal=$compratotal&parcelas=$parcelas&url=$urlretorno&cielo_numero=$cielo_numero&cielo_chave=$cielo_chave");
          ob_start();
          curl_exec($ch);
          curl_close($ch);
          $file_contents = ob_get_contents();
          ob_end_clean();

          $retornowbcielo  = explode(":", $file_contents);
          $cielo_tid       = utf8_encode(TidADS($retornowbcielo[0]));
          $cielo_mensagem  = utf8_encode($retornowbcielo[1]);
          $cielo_codigo    = $retornowbcielo[2];
          $cielo_lr        = $retornowbcielo[3];
          $retornaorderadd = $retornowbcielo[4];
          $cielolrmsg      = $this->getMsgRetornoCielo($cielo_lr);
          $comentario      = "Cielo: " . $cielo_mensagem . " - ";
          $comentario     .= "TID: " . $cielo_tid . " - ";
          $comentario     .= "" . $bandeira . " - ".$parcelas." x R$ ".number_format($valor,2,'.','');

          if (($cielo_lr=='00')||($cielo_lr=='11')) {
            $autoricao = 'autorizada';
          } else if (($cielo_lr=='06')||($cielo_lr=='96')) {
            if ($this->session->data['cielo_retentativa'] < 3){
              $autoricao = 'retentativa';
              $this->session->data['cielo_retentativa'] += 1;
            }else{
              unset($this->session->data['cielo_retentativa']);
              $autoricao = 'reprovada';
            }

          } else {
            $autoricao = 'reprovada';
          }


          if ($parcelas <= $this->config->get('cielo_transparente_parcela_semjuros')){
            $comentario .= " Sem Juros";
          }  else {
            $comentario .= " Com Juros (".$this->config->get('cielo_transparente_parcela_juros')."% ao m&ecirc;s)";
          }

          $this->session->data['cielotransparente_TID'] = $cielo_tid;
          $this->session->data['cielotransparente_LR']   = $cielo_lr.' - '.$cielolrmsg;
          if (($retornaorderadd == 'Aprovado')&&($autoricao == 'autorizada')) {
            $this->session->data['cielotransparente_confirmacao'] = Type_StCieloPagamento::Tp_CieloPago ;
            $this->model_payment_cielo_transparente->setOrderCielo($cielo_tid,$cielo_lr,$cielolrmsg, Type_StCieloPagamento::Tp_CieloPago,$pedidoloja,$vvalorcielo,$tipocartao,$bandeira,$parcelas);
            $this->dmodel_checkout_order->confirm($this->session->data['order_id'], $this->config->get('cielo_transparente_order_status_id'), $comentario);
            $this->data['continue'] = $this->url->link('checkout/success');
          } else if ($autoricao <> 'retentativa'){
            $this->session->data['cielotransparente_confirmacao'] = Type_StCieloPagamento::Tp_CieloCancelado;
            $this->dmodel_checkout_order->confirm($this->session->data['order_id'], $this->config->get('cielo_transparente_order_status_cancelado_id'), $comentario);
            $this->data['continue'] = $this->url->link('checkout/success');
          }

        }
      }else{
        $autoricao = 'autorizada';
      }

      if ((isset($this->session->data['order_id']))&&($autoricao<>'retentativa')) {
        $this->cart->clear();
        unset($this->session->data['shipping_method']);
        unset($this->session->data['shipping_methods']);
        unset($this->session->data['payment_method']);
        unset($this->session->data['payment_methods']);
        unset($this->session->data['comment']);
        unset($this->session->data['coupon']);
        unset($this->session->data['cielo_retentativa']);
      }

      $json['autorizacao'] = $autoricao;

    }else{

      if (isset($this->error['error_bandeira'])){
        $json['error']['bandeira'] = $this->error['error_bandeira'];
      }
      if (isset($this->error['error_nomecartao'])){
        $json['error']['nomecartao'] = $this->error['error_nomecartao'];
      }
      if (isset($this->error['error_numerocartao'])){
        $json['error']['numerocartao'] = $this->error['error_numerocartao'];
      }
      if (isset($this->error['error_csv'])){
        $json['error']['csv'] = $this->error['error_csv'];
      }
      if (isset($this->error['error_validade'])){
        $json['error']['validade'] = $this->error['error_validade'];
      }

    }

    $this->response->setOutput(json_encode($json));

  }

  public function validate(){

    if(!isset($this->request->post['creditcard_cctype'])){
      $this->error['error_bandeira'] = $this->language->get('error_bandeira');
    }
    if(!isset($this->request->post['creditcard_name'])||strlen($this->request->post['creditcard_name']) == ''){
      $this->error['error_nomecartao'] = $this->language->get('error_nomecartao');
    }
    if(!isset($this->request->post['creditcard_ccno'])||strlen($this->request->post['creditcard_ccno']) == ''){
      $this->error['error_numerocartao'] = $this->language->get('error_numerocartao');
    }
    if(!isset($this->request->post['creditcard_cccvd'])||strlen($this->request->post['creditcard_cccvd']) == ''){
      $this->error['error_csv'] = $this->language->get('error_csv');
    }
    if(!isset($this->request->post['expire'])||(strlen($this->request->post['expire']) == '')||(strlen($this->request->post['expire']) != 7/*99/9999*/)){
      $this->error['error_validade'] = $this->language->get('error_validade');
    }

    if (!$this->error) {
      return true;
    } else {
      return false;
    }
  }

  public function parcelamento() {
    if (isset($this->request->get['bandeira'])) {
      $bandeira = $this->request->get['bandeira'];
    } else {
      $bandeira = null;
    }

    if (isset($this->request->get['parcelas'])) {
      $maximo_parcelas = $this->request->get['parcelas'];
    } else {
      $maximo_parcelas = 0;
    }

    $this->load->dmodel('checkout/order');
    $order_info  = $this->dmodel_checkout_order->getOrder($this->session->data['order_id']);

    $valor = str_replace(',','',number_format($order_info['total'],2));

    $parcelas_sem_juros = $this->config->get('cielo_transparente_parcela_semjuros');

    $juros = $this->config->get('cielo_transparente_parcela_juros');

    $parcela_minima = $this->config->get('cielo_transparente_parcela_minimo');

    $parcelamento = '';
    $info = '';

    if (!empty($bandeira)) {
      $parcelamento .= '
      <label class="required-label" for="formaPagamento">Valor</label>
      <select name="formaPagamento" id="formaPagamento" style="height:40px;">
      <option value="1|'.$valor.'">1x de '. number_format($valor, 2, ',', '.') .' sem juros</option>';

      for ($p = 2; $p <= $maximo_parcelas; $p++) {
        $valor_parcela = 0;

        if ($p <= $parcelas_sem_juros) {
          $valor_parcela = $valor / $p;
        }

        if ($p > $parcelas_sem_juros) {
          $valor_parcela = $this->juroComposto($valor, $p, $juros, 1);
        }

        if ($valor_parcela >= $parcela_minima) {
          if ($p <= $parcelas_sem_juros) {
            $parcelamento .= '<option value="'. $p .'|'.$valor_parcela.'"> '. $p .'x de '. number_format($valor_parcela, 2, ',', '.') .' sem juros</option>';
          } else {
            $parcelamento .= '<option value="' . $p . '|'.$valor_parcela.'"> ' . $p . 'x de ' . number_format($valor_parcela, 2,',','.') . ' com juros</option>';
          }
        } else {
          $info .= '<span class="help-inline fixed-help">Parcela m&iacute;nima de '. number_format($parcela_minima, 2, ',', '.') .'</span>&nbsp;&nbsp;-&nbsp;&nbsp;';
          break;
        }
      }
      if ($parcelas_sem_juros < $maximo_parcelas) {
        $juros = !empty($juros) ? preg_replace('/[^0-9\s]+/', ',', $juros) : 0;
        $info .= '<span class="help-inline fixed-help">Juros de '. $juros .'% ao m&ecirc;s</span>';
      }

    $parcelamento .= '</select>' . $info;
  }

  $this->response->setOutput($parcelamento);
}

public function getMsgRetornoCielo($value){
	if (in_array($value,$this->arrayMsgRetornoCielo)){
		return $this->arrayMsgRetornoCielo[$value];
	}else{
		return "Código não especificado";
	}
}

public $arrayMsgRetornoCielo = array(
  //Códigos de resposta de autorização (LR) - Erros que ocorrem por falha na transação
  '00' => 'Transação Autorizada - Nacional',
  '01' => 'Transação referida pelo banco emissor',
  '04' => 'Existe algum tipo de restri&ccedil;&atilde;o no cart&atilde;o',
  '05' => 'Transa&ccedil;&atilde;o N&atilde;o Autorizada Pelo Banco',
  '06' => 'Tente novamente',
  '07' => 'Cartão com restrição',
  '08' => 'C&oacute;digo de seguran&ccedil;a inv&aacute;lido',

  '0' => 'Transação Autorizada - Nacional',
  '1' => 'Transação referida pelo banco emissor',
  '4' => 'Existe algum tipo de restri&ccedil;&atilde;o no cart&atilde;o',
  '5' => 'Transa&ccedil;&atilde;o N&atilde;o Autorizada Pelo Banco',
  '6' => 'Tente novamente',
  '7' => 'Cartão com restrição',
  '8' => 'C&oacute;digo de seguran&ccedil;a inv&aacute;lido',

  '11' => 'Transação Autorizada - Internacional',
  '13' => 'Valor Inválido',
  '14' => 'Cartão Inválido',
  '15' => 'Banco Emissor Indisponível',
  '21' => 'Cancelamento não efetuado',
  '41' => 'Cartão com restrição',
  '51' => 'Saldo insulficiente',
  '54' => 'Cartão Vencido',
  '57' => 'Transação não permitida',
  '60' => 'Transação não autorizada',
  '62' => 'Transação não autorizada',
  '78' => 'Cartão bloqueado',
  '82' => 'Erro no cartão',
  '91' => 'Banco Indisponível',
  '96' => 'Tente novamente',
  'AA' => 'Tempo Excedido',
  'AC' => 'Cartão de débito utilizando a função crédito',
  'GA' => 'Transação Referida pela Cielo',

  //Catálogo de resposta de erros (Erros no XML de envio) - Erros que ocorrem por falha no ambiente/configuração
  //Alguns erros são parecidos, mas os que ocorrem abaixo podem ser devido a alguma formatação errada dentro do XML enviado
  '001' => 'Mensagem Inválida (XML Fora do formato especificado',
  '002' => 'Credenciais inválidas',
  '003' => 'Transação inexistente',
  '008' => 'Código de seguraça inválido',
  '010' => 'Inconscistência no envio do cartão',
  '011' => 'Modalidade de Pagamento não Habilitada',
  '012' => 'Número de parcelas inválido',
  '013' => 'Flag de autorização automática inválida',
  '014' => 'Autorização Direta inválida',
  '015' => 'Autorização Direta sem Cartão',
  '016' => 'Identificador, TID, inválido',
  '017' => 'Código de Segurança Ausente',
  '018' => 'Indicador de Código de Segurança Inconsistente',
  '019' => 'URL de Retorno não Fornecida',
  '020' => 'Status não permite Autorização',
  '021' => 'Prazo de Autorização Vancido',
  '025' => 'Encaminhamento a Autorização Não Permitido',
  '030' => 'Status Inválido para Captura',
  '031' => 'Prazo de Captura Vencido',
  '032' => 'Valor de Captura Inválido',
  '033' => 'Falha ao Capturar',
  '034' => 'Valor da Taxa de Embarque Obrigatório',
  '035' => 'Bandeira inválida para utilização da Taxa de Embarque',
  '036' => 'Bandeira inválida para utilização da Taxa de Embarque',
  '040' => 'Prazo de cancelamento vencido',
  '041' => 'Status não permite Cancelamento',
  '042' => 'Falha ao Cancelar',
  '043' => 'Valor de Cancelamento é maior que valor autorizado',
  '051' => 'Recorrência Inválida',
  '052' => 'Token Inválido',
  '053' => 'Recorrência não habilitada',
  '054' => 'Transação com Token Inválida',
  '055' => 'Número do Cartão não Fornecido',
  '056' => 'Validade do Cartão não Fornecido',
  '057' => 'Erro inesperado gerando Token',
  '061' => 'Transação Recorrente Inválida',
  '097' => 'Sistema Indisponível',
  '098' => 'Timeout (25 segundos)',
  '099' => 'Erro Inesperado'
);

  public function app() {
    $this->document->addScriptApp(array(
      'catalog/view/javascript/jquery.payment/jquery.payment.js',
      'catalog/view/theme/appmobile/js/payment.cielo-transparente.js'
    ));
    $this->data['scriptsApp'] = json_encode($this->document->getScriptsApp());
  }
}
