<?php
require_once (DIR_SYSTEM . "library/Cielo/config.php");

class ControllerPaymentCielo extends Controller {

	public function displayCartoes(){

		$cielo_total = isset($this->session->data['cielo_total']) ? $this->session->data['cielo_total'] : '';

		// valida o valor total da compra
		if( !is_numeric($cielo_total) ){
			echo('<script>document.location.href = "'.$this->url->link('checkout/checkout', 'm2&e10', 'SSL').'";</script>');
			exit;
		}

		$this->load->model('payment/cielo');

		$cartoes_ativados = $this->model_payment_cielo->getCartoesAtivados($cielo_total);

		// verifica se existe algum cartao ativado e valido
		if(count($cartoes_ativados) == 0){
			echo('<script>document.location.href = "'.$this->url->link('checkout/checkout', 'm2&e20', 'SSL').'";</script>');
			exit;
		}

		$this->language->load('payment/cielo');

		$this->data['text_selecione_cartao'] = $this->language->get('text_selecione_cartao');
		$this->data['cartoes'] = array();

		$text_cartao_titulo = $this->language->get("text_cartao_titulo");
		$text_a_vista = $this->language->get("text_a_vista");
		$text_parcelado = $this->language->get("text_parcelado");

		foreach($cartoes_ativados as $cartao){

			$cartao_nome = $this->language->get("title_{$cartao}");

			$opcoes_parcelamento = $this->model_payment_cielo->calculaParcelas($cartao,$cielo_total);

			$cartao_max_parcelas = max(array_keys($opcoes_parcelamento));
			$cartao_valor_parcela = $this->currency->format( $opcoes_parcelamento[$cartao_max_parcelas]['valor'] , 'BRL');

			if($cartao_max_parcelas == 1){
				$cartao_pagamento = sprintf($text_a_vista, $cartao_valor_parcela);
			}else{
				$cartao_pagamento = sprintf($text_parcelado, $cartao_max_parcelas, $cartao_valor_parcela);
			}

			$this->data['cartoes'][$cartao] = sprintf($text_cartao_titulo, $cartao_nome, $cartao_pagamento);
		}

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

		$this->response->setOutput($this->render());

	} // displayCartoes





	public function displayParcelas(){

		$cartao = isset($this->request->get['c']) ? trim($this->request->get['c']) : '';
		$cielo_total = isset($this->session->data['cielo_total']) ? $this->session->data['cielo_total'] : '';

		$this->load->model('payment/cielo');

		// valida o cartao escolhido
		if( ! $this->model_payment_cielo->validaCartao($cartao) ){
			echo('<script>document.location.href = "'.$this->url->link('checkout/checkout', 'm3&e10', 'SSL').'";</script>');
			exit;
		}

		// valida o valor total da compra
		if( !is_numeric($cielo_total) ){
			echo('<script>document.location.href = "'.$this->url->link('checkout/checkout', 'm3&e20', 'SSL').'";</script>');
			exit;
		}

		$opcoes_parcelamento = $this->model_payment_cielo->calculaParcelas($cartao,$cielo_total);

		if(count($opcoes_parcelamento) == 0){
			echo('<script>document.location.href = "'.$this->url->link('checkout/checkout', 'm3&e30', 'SSL').'";</script>');
			exit;
		}

		$this->session->data['cielo_opcoes_parcelamento'] = $opcoes_parcelamento;

		$this->language->load('payment/cielo');

		$this->data['text_selecione_forma_pgto'] = $this->language->get('text_selecione_forma_pgto');
		$this->data['text_observacoes'] = '';
		$this->data['parcelas'] = $opcoes_parcelamento;

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

		$this->response->setOutput($this->render());

	} // displayParcelas





	public function index() {
		$cartao = isset($this->session->data['cielo_cartao']) ? $this->session->data['cielo_cartao'] : '';
		$parcelas = isset($this->session->data['cielo_parcelas']) ? intval($this->session->data['cielo_parcelas']) : 0;
		$parcelamento = isset($this->session->data['cielo_opcoes_parcelamento']) ? $this->session->data['cielo_opcoes_parcelamento'] : array();
		$order_id = isset($this->session->data['order_id']) ? intval($this->session->data['order_id']) : 0;

		$this->load->model('payment/cielo');

		// valida o cartao escolhido
		if( ! $this->model_payment_cielo->validaCartao($cartao) ){
			$json['redirect'] = $this->url->link('checkout/checkout', 'm1&e10', 'SSL');
			echo json_encode($json);
			exit;
		}

		// valida o parcelamento escolhido
		if( ! $this->model_payment_cielo->validaParcelamento($cartao, $parcelas) ){
			$json['redirect'] = $this->url->link('checkout/checkout', 'm1&e20', 'SSL');
			echo json_encode($json);
			exit;
		}

		// valida opcoes de parcelamento
		if( !isset($parcelamento[$parcelas]['valor']) ){
			$json['redirect'] = $this->url->link('checkout/checkout', 'm1&e30', 'SSL');
			echo json_encode($json);
			exit;
		}

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

		// valida o pedido
		if($order_info === FALSE){
			$json['redirect'] = $this->url->link('checkout/checkout', 'm1&e40', 'SSL');
			echo json_encode($json);
			exit;
		}

		$total = $order_info['total'];

		// por seguranca, guarda opcoes de parcelamento para serem usadas na confirmacao
		$this->session->data['cielo_confirm_parcelamento'] = $parcelamento;

		$this->language->load('payment/cielo');

		$cartao_nome = $this->language->get("title_{$cartao}");
		$descricao_parcela = $parcelamento[$parcelas]['descricao'];

		$this->data['cartao'] =  $cartao;
		$this->data['cartao_nome'] =  $cartao_nome;
		$this->data['cartao_opcao'] =  $descricao_parcela;
		$this->data['text_confirm'] =  $this->language->get('text_confirm');
		$this->data['text_information'] =  $this->language->get('text_information');
		$this->data['button_confirm'] = $this->language->get('button_confirm');

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

		$this->render();

	} // index





	public function confirm(){
		$cartao = isset($this->session->data['cielo_cartao']) ? $this->session->data['cielo_cartao'] : '';
		$parcelas = isset($this->session->data['cielo_parcelas']) ? intval($this->session->data['cielo_parcelas']) : 0;
		$confirm_parcelamento = isset($this->session->data['cielo_confirm_parcelamento']) ? $this->session->data['cielo_confirm_parcelamento'] : array();
		$order_id = isset($this->session->data['order_id']) ? intval($this->session->data['order_id']) : 0;

		$this->load->model('payment/cielo');

		// valida o cartao escolhido
		if( ! $this->model_payment_cielo->validaCartao($cartao) ){
			$json['redirect'] = $this->url->link('checkout/checkout', 'm4&e10', 'SSL');
			echo json_encode($json);
			exit;
		}

		// valida o parcelamento escolhido
		if( ! $this->model_payment_cielo->validaParcelamento($cartao, $parcelas) ){
			$json['redirect'] = $this->url->link('checkout/checkout', 'm4&e20', 'SSL');
			echo json_encode($json);
			exit;
		}

		// valida opcoes de parcelamento
		if( !isset($confirm_parcelamento[$parcelas]['valor']) ){
			$json['redirect'] = $this->url->link('checkout/checkout', 'm4&e40', 'SSL');
			echo json_encode($json);
			exit;
		}

		$this->load->model('checkout/order');
		$order_info = $this->model_checkout_order->getOrder($order_id);

		// valida o pedido
		if($order_info === FALSE){
			$json['redirect'] = $this->url->link('checkout/checkout', 'm4&e30', 'SSL');
			echo json_encode($json);
			exit;
		}

		//$total = $order_info['total'];

		// pega o total ja gravado na sessao para nao calcular duas vezes o juros ou desconto
		$total = $confirm_parcelamento[$parcelas]['total'];

		// gera codigo unico para identificacao da transacao no retorno
		$code = md5(microtime(true));

		// define a url que fara o tratamento do retorno
		$url_retorno = $this->url->link('payment/cielo/retorno', 'c='.$code, 'SSL');

		// envia requisicao
		$resposta = $this->model_payment_cielo->requisicaoTransacao($cartao, $parcelas, $total, $order_id, $url_retorno);

		if($resposta === FALSE OR !isset($resposta['tid']) OR !isset($resposta['url-autenticacao'])){

			$this->language->load('payment/cielo');

			$json['error'] = $this->language->get('error_envio');
			$json['redirect'] = $this->url->link('checkout/checkout', 'm4&e50', 'SSL');

		}else{

			$dados['tid'] = $resposta['tid'];
			$dados['code'] = $code;
			$dados['order_id'] = $order_id;
			$dados['valor'] = intval($resposta['dados-pedido']['valor']) / 100;
			$dados['datahora'] = str_replace('T', ' ', substr($resposta['dados-pedido']['data-hora'], 0, 19));
			$dados['bandeira'] = $resposta['forma-pagamento']['bandeira'];
			$dados['produto'] = $resposta['forma-pagamento']['produto'];
			$dados['parcelas'] = $resposta['forma-pagamento']['parcelas'];
			$dados['autorizar'] = $this->config->get("cielo_{$cartao}_tipo_autorizacao");
			$dados['capturar'] = $this->config->get("cielo_{$cartao}_captura_automatica");

			$this->model_payment_cielo->addTransaction($dados);

			$json['redirect'] = $resposta['url-autenticacao'];
		}

		echo json_encode($json);

	} // confirm





	public function retorno() {
		$code = isset($this->request->get['c']) ? trim($this->request->get['c']) : '';

		// valida o codigo identificador da transacao
		if($code == ''){
			$this->redirect($this->url->link('checkout/success', 'cielo=2&m5&e10'));
		}

		// busca o tid pelo codigo identificador
		$this->load->model('payment/cielo');
		$transacao = $this->model_payment_cielo->getTransactionByCode($code);

		// valida o tid retornado
		if( !isset($transacao['tid']) ){
			$this->redirect($this->url->link('checkout/success', 'cielo=2&m5&e20'));
		}

		$tid = $transacao['tid'];
		$tid_status = $transacao['status'];
		$capturar = $transacao['capturar'];

		// faz a consulta na cielo
		$resposta = $this->model_payment_cielo->requisicaoConsulta($tid);

		// valida a resposta da consulta
		if($resposta === FALSE OR !isset($resposta['status']) OR !isset($resposta['dados-pedido']['numero'])){
			// por seguranca, antes de redirecionar o cliente para uma mensagem
			// faz 3 tentativas de consulta em caso de erro de comunicacao com a cielo
			$cielo_retorno_erro = isset($this->session->data['cielo_retorno_erro']) ? intval($this->session->data['cielo_retorno_erro']) : 0;
			if($cielo_retorno_erro < 3){
				// incrementa o contador de erros
				$this->session->data['cielo_retorno_erro'] = ++$cielo_retorno_erro;
				// faz uma pausa dentre as tentativas
				sleep(10);
				// redireciona novamente para este mesmo metodo
				$this->redirect($this->url->link('payment/cielo/retorno', 'c='.$code, 'SSL'));
			}else{
				// reseta o contador de erros
				$this->session->data['cielo_retorno_erro'] = 0;
				// redireciona para a mensagem caso ocorram mais de 3 tentativas consecutivas com falha
				$this->redirect($this->url->link('checkout/success', 'cielo=2&m5&e30'));
			}
		}

		// pega status da transacao na cielo
		$new_tid_status = $resposta['status'];

		// se houver mudanca de status atualiza a transacao
		if($new_tid_status != $tid_status){
			// atualiza status da transacao cielo
			$this->model_payment_cielo->updateTransaction($tid, $new_tid_status);
		}

		$order_id = $resposta['dados-pedido']['numero'];
		$total = $this->currency->format(intval($resposta['dados-pedido']['valor'])/100, 'BRL');

		$bandeira = $resposta['forma-pagamento']['bandeira'];
		$produto = $resposta['forma-pagamento']['produto'];
		$parcelas = $resposta['forma-pagamento']['parcelas'];

		if($produto == 'A'){
			// se for debito pega a bandeira correta
			$bandeira = cieloCreditToDebit($bandeira);
		}

		$this->load->model('checkout/order');
		$order_info = $this->model_checkout_order->getOrder($order_id);

		// valida o pedido
		if($order_info === FALSE){
			$this->redirect($this->url->link('checkout/success', 'cielo=2&m5&e40'));
		}

		// pega o status atual do pedido
		$order_status_id = $order_info['order_status_id'];

		// faz a confirmacao do pedido caso seja preciso
		if($new_tid_status != '5' AND $new_tid_status != '9' AND $order_status_id == '0'){
			$order_status_id = $this->config->get('cielo_status_pendente');
			$this->model_checkout_order->confirm($order_id, $order_status_id);
		}

		$this->language->load('payment/cielo');

		$cartao = $this->language->get("title_{$bandeira}");
		$notify = (bool) $this->config->get('cielo_update_status_alert');
		$finalizada = TRUE;

		if($new_tid_status == '4' AND !$capturar){ // 4 = autorizada (falta capturar)
			$situacao = $this->language->get('cielo_historico_status_autorizada');
			$new_order_status_id = $this->config->get('cielo_status_pendente');
			$redirect = '1';

		}elseif($new_tid_status == '5'){ // 5 = nao autorizada
			$situacao = $this->language->get('cielo_historico_status_nao_autorizada');
			$new_order_status_id = $this->config->get('cielo_status_nao_aprovada');
			$redirect = '0';

		}elseif($new_tid_status == '6'){ // 6 = capturada
			$situacao = $this->language->get('cielo_historico_status_capturada');
			$new_order_status_id = $this->config->get('cielo_status_aprovada');
			$redirect = '1';

		}elseif($new_tid_status == '9'){ // 9 = cancelada
			$situacao = $this->language->get('cielo_historico_status_cancelada');
			$new_order_status_id = $this->config->get('cielo_status_nao_aprovada');
			$redirect = '0';

		}else{
			$situacao = sprintf($this->language->get('cielo_historico_status_outros'), cieloGetStatus($new_tid_status) );
			$new_order_status_id = $this->config->get('cielo_status_pendente');
			$notify = FALSE;
			$finalizada = FALSE;
			$redirect = '2';
		}

		// se houver mudanca de status atualiza o pedido
		if($new_tid_status != $tid_status OR $new_order_status_id != $order_status_id){
			// faz atualizacao do pedido
			$comentario = $situacao."\n";
			$comentario .= sprintf($this->language->get('cielo_historico_pagamento'), $total, $cartao, $parcelas)."\n";
			$comentario .= "TID: {$tid}";

			$this->model_checkout_order->update($order_id, $new_order_status_id, $comentario, $notify);
		}

		if($finalizada){
			$this->model_payment_cielo->finalizaTransaction($tid);
		}

		$this->redirect($this->url->link('checkout/success', 'cielo='.$redirect));

	} // retorno

}
