<?php


/*

 ************************************************************************

 Copyright [2013] [PagSeguro Internet Ltda.]



 Licensed under the Apache License, Version 2.0 (the "License");

 you may not use this file except in compliance with the License.

 You may obtain a copy of the License at



 http://www.apache.org/licenses/LICENSE-2.0



 Unless required by applicable law or agreed to in writing, software

 distributed under the License is distributed on an "AS IS" BASIS,

 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 See the License for the specific language governing permissions and

 limitations under the License.

 ************************************************************************

 */


/**
 * Controller Payment PagSeguro
 * Class responsible for payment PagSeguro.
 */

include_once 'PagSeguroLibrary/PagSeguroLibrary.php';
$loader = $this->registry->get('load');
$loader->controller('payment/payment_default');

class ControllerPaymentPagSeguro extends ControllerPaymentPaymentDefault

{


    /**
     *
     * @var pagSeguroPaymentRequestObject
     */

    private $_pagSeguroPaymentRequestObject;


    /**
     * Credential
     * @var credential
     */

    private $_credential;


    /**
     * model_checkout_order->getOrder
     * @var array
     */

    private $_order_info;


    /**
     * Url PagSeguro
     * @var url
     */

    private $_urlPagSeguro;


    /**
     * Version API
     * @var version
     */

    private $api_version = '1.0';


    /**
     * The first method to be called by the payment PagSeguro treatment.
     */

    protected function index()
    {
        parent::index();

        $this->app();


        $this->_load();

        $this->_retrievePagSeguroModuleVersion();

        $this->_setCmsVersion();

        $this->_generatePagSeguroOrderStatus();


        $this->_order_info = $this->dmodel_checkout_order->getOrder($this->session->data['order_id']);

        $this->_pagSeguroPaymentRequestObject = $this->_generatePagSeguroPaymentRequestObject();

        $this->_pagSeguroPaymentRequestObject->setReference($this->session->data['order_id']);


        $this->_performPagSeguroRequest($this->_pagSeguroPaymentRequestObject);


        $this->data['captcha_tpl'] = $this->getChild('payment/captcha');

        $this->data['button_confirm'] = $this->language->get('button_confirm');

        $this->data['continue'] = $this->_action();

        $this->template = 'default/template/payment/pagseguro.tpl';


        $this->render('payment/pagseguro');

    }

    public function recomprarPagseguro()
    {

        if (isset($this->request->get['order_id'])) {
            $this->session->data['order_id'] = $this->request->get['order_id'];

            $this->_load();

            $this->_retrievePagSeguroModuleVersion();

            $this->_setCmsVersion();

            $this->_generatePagSeguroOrderStatus();

            $this->_order_info = $this->dmodel_checkout_order->getOrder($this->session->data['order_id']);

            $order_itens = $this->dmodel_checkout_order->getOrderProducts($this->session->data['order_id']);

            $order_total = $this->dmodel_checkout_order->getOrderSubTotals($this->session->data['order_id']);

            $this->_pagSeguroPaymentRequestObject = $this->_generatePagSeguroPaymentRequestObject($order_itens, $order_total);

            $this->_pagSeguroPaymentRequestObject->setReference($this->session->data['order_id']);

            $this->_performPagSeguroRequest($this->_pagSeguroPaymentRequestObject);

            header('Location:' . $this->_action() . '');
        }


    }


    public function confirm()
    {
        $json = array();
        $json['error'] = $this->validate();

        if (!$json['error']) {
            $this->_updateOrderStatus();
        }

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

    }


    /**
     * Load model and language
     */

    private function _load()

    {
        $this->load->type('tipocomum');

        $environment = ($this->config->get('pagseguro_environment_status')) ? $this->config->get('pagseguro_environment_status') : Type_Environment::Tp_Production;

        PagSeguroConfig::activeLog($this->_getDirectoryLog());

        PagSeguroConfig::setEnvironment($environment);//seta qual ambiente estara em execução

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

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

        $this->load->model('setting/setting');

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

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

    }


    /**
     * Retrieve PagSeguro osCommerce module version
     */

    private function _retrievePagSeguroModuleVersion()

    {

        PagSeguroLibrary::setModuleVersion('eFutura: 1.0');

    }


    /**
     * Set version CMS
     */

    private function _setCmsVersion()

    {

        PagSeguroLibrary::setCMSVersion('eFutura: 1.0');

    }


    /**
     * Generate PagSeguro Payment Request
     * @return \PagSeguroPaymentRequest
     */

    private function _generatePagSeguroPaymentRequestObject($order_itens = '', $order_total = '')

    {

        $paymentRequest = new PagSeguroPaymentRequest();

        $paymentRequest->setCurrency(PagSeguroCurrencies::getIsoCodeByName("REAL"));

        $paymentRequest->setExtraAmount($this->_generateExtraAmount($order_total));

        $paymentRequest->setRedirectURL($this->_getPagSeguroRedirectUrl());

        $paymentRequest->setNotificationURL($this->_getPagSeguroNotificationURL());

        $paymentRequest->setItems($this->_generatePagSeguroProductsData($order_itens));

        $paymentRequest->setSender($this->_generatepagSeguroSenderDataObject());

        $paymentRequest->setShipping($this->_generatePagSeguroShippingDataObject());

        $paymentRequest->setMaxAge(86400);

        if (($this->config->get('pagseguro_boleto_desconto') > 0)) {
            $value = str_replace(',', '.', $this->config->get('pagseguro_boleto_desconto'));
            $paymentRequest->addPaymentMethodConfig('BOLETO', $value, 'DISCOUNT_PERCENT');
        }

        if (($this->config->get('pagseguro_cartao_credito_desconto') > 0)) {
            $value = str_replace(',', '.', $this->config->get('pagseguro_cartao_credito_desconto'));
            $paymentRequest->addPaymentMethodConfig('CREDIT_CARD', $value, 'DISCOUNT_PERCENT');
        }

        if (($this->config->get('pagseguro_debito_desconto') > 0)) {
            $value = str_replace(',', '.', $this->config->get('pagseguro_debito_desconto'));
            $paymentRequest->addPaymentMethodConfig('EFT', $value, 'DISCOUNT_PERCENT');
        }

        if (($this->config->get('pagseguro_deposito_desconto') > 0)) {
            $value = str_replace(',', '.', $this->config->get('pagseguro_deposito_desconto'));
            $paymentRequest->addPaymentMethodConfig('DEPOSIT', $value, 'DISCOUNT_PERCENT');
        }


        return $paymentRequest;
    }


    /**
     * Generate Extra Amount.
     * @return double
     */

    private function _generateExtraAmount($order_total = '')

    {

        $_extra = 0;

        $_shipping_cost = $this->_generatePagSeguroShippingCost();

        $_sub_total = ($order_total != '') ? $order_total : $this->cart->getSubTotal();

        $_order_total = $this->_order_info['total'];


        if (($_shipping_cost + $_sub_total) != $_order_total) {


            if ($_shipping_cost != 0) {

                $_order_total = $_order_total - $_shipping_cost;

            }

            $_extra = $_order_total - $_sub_total;

        }

        return $this->currency->format($_extra, $this->_order_info['currency_code'], false, false);

    }


    /**
     * PagSeguro Redirect url
     * @return redirect url
     */

    private function _getPagSeguroRedirectUrl()

    {


        if ($this->_isNotNull($this->config->get('pagseguro_forwarding')))

            return $this->config->get('pagseguro_forwarding');


        return $this->config->get('config_ssl') . "index.php?route=checkout/success";


    }


    /**
     * PagSeguro notification url
     * @return notification url
     */

    private function _getPagSeguroNotificationURL()

    {


        if ($this->_isNotNull($this->config->get('pagseguro_url_notification')))

            return $this->config->get('pagseguro_url_notification');


        return $this->config->get('config_ssl') . "index.php?route=payment/pagseguro_notification";

    }


    /**
     * Generate PagSeguro Products
     * @return array
     */

    private function _generatePagSeguroProductsData($order_itens = '')

    {


        $pagSeguroItens = array();

        $cont = 1;

        $products = ($order_itens != '') ? $order_itens : $this->cart->getProducts();

        foreach ($products as $product) {

            $peso = $product['weight'] * 1000;

            $pagSeguroItem = new PagSeguroItem();

            $pagSeguroItem->setId($cont++);

            $pagSeguroItem->setDescription(substr($product['name'], 0, 100));

            $pagSeguroItem->setQuantity($product['quantity']);

            $pagSeguroItem->setAmount(str_replace("R$", "", $this->currency->format($product['price'], $this->_order_info['currency_code'], false, false)));

            $pagSeguroItem->setWeight(ceil($peso));


            array_push($pagSeguroItens, $pagSeguroItem);

        }

        return $pagSeguroItens;

    }


    /**
     * Generate PagSeguro Sender Data
     * @return \PagSeguroSender
     */

    private function _generatepagSeguroSenderDataObject()

    {


        $sender = new PagSeguroSender();

        $sender->setEmail(str_replace(' ', '', $this->_order_info['email']));

        $sender->setName($this->_order_info['firstname'] . ' ' . $this->_order_info['lastname']);


        /*$documents = array('0'=>array('type'=>'cpf', 'value'=>'403.228.228.58'));

        $sender->setDocuments($documents);*/


        return $sender;

    }


    /**
     * Generate PagSeguro Shipping Data
     * @return \PagSeguroShipping
     */

    private function _generatePagSeguroShippingDataObject()

    {

        $shipping = new PagSeguroShipping();

        $shipping->setAddress($this->_generatePagSeguroShippingAddressDataObject());

        $shipping->setType($this->_generatePagSeguroShippingTypeObject());

        $shipping->setCost(str_replace("R$", '', $this->currency->format($this->_generatePagSeguroShippingCost(), $this->_order_info['currency_code'], false, false)));

        return $shipping;

    }


    /**
     * Generate PagSeguro Shipping Address
     * @return \PagSeguroAddress
     */

    private function _generatePagSeguroShippingAddressDataObject()

    {


        $address = new PagSeguroAddress();

        $address->setCity(html_entity_decode($this->_order_info['payment_city']));

        $address->setPostalCode(html_entity_decode($this->_order_info['payment_postcode']));

        $address->setStreet(html_entity_decode($this->_order_info['payment_address_1']));

        $address->setDistrict(html_entity_decode($this->_order_info['payment_zone']));

        $address->setCountry($this->_order_info['payment_iso_code_2']);

        $address->setNumber($this->_order_info['payment_numero']);

        return $address;

    }


    /**
     * Generate PagSeguro Shipping Type
     * @return \PagSeguroShippingTyp
     */

    private function _generatePagSeguroShippingTypeObject()

    {


        $shippingType = new PagSeguroShippingType();

        $shippingType->setByType('NOT_SPECIFIED');

        return $shippingType;

    }


    /**
     * Generate PagSeguro Shipping Cost
     * @return double
     */

    private function _generatePagSeguroShippingCost()

    {

        $_value = 0;


        if (!empty($this->_order_info['shipping_code'])) {

            $_shipping_code = $this->_order_info['shipping_code'];

            $_shipping_cost = explode(".", $_shipping_code);


            if ($_shipping_cost['0'] != 'free') {

                //$_array_setting = $this->model_setting_setting->getSetting($_shipping_cost['0']);

                /* sรณ funciona para taxa fixa de frete, caso nao tenha, retorna zero para entrar em outras taxas

				no site do pagseguro... mardito pagseguro q nao fez uma funcao mais dinamica :/ byMatheus */

                /*if (!empty($_array_setting[$_shipping_cost['0'] . "_cost"]))

                    $_value = $_array_setting[$_shipping_cost['0'] . "_cost"];*/

                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_total WHERE order_id = '" . (int)$this->session->data['order_id'] . "' AND code = 'shipping'");

                return $query->row['value'];

            }

        }


        return $_value;

    }


    /**
     * Perform PagSeguro Request
     * @param PagSeguroPaymentRequest $paymentRequest
     */

    private function _performPagSeguroRequest(PagSeguroPaymentRequest $paymentRequest)

    {

        $this->_credential = new PagSeguroAccountCredentials($this->config->get('pagseguro_email'), $this->config->get('pagseguro_token'));


        try {

            $this->_urlPagSeguro = $paymentRequest->register($this->_credential);

        } catch (Exception $exc) {
            $this->log->write(print_r($exc, true));
            die($this->language->get('text_info'));

        }

    }


    /**
     * Generate PagSEguro Order Status
     */

    private function _generatePagSeguroOrderStatus()

    {

        $this->model_payment_pagseguro->savePagSeguroOrderStatus();

    }


    /**
     * Update Order Status
     */

    private function _updateOrderStatus()

    {

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

        $this->dmodel_checkout_order->confirm($this->session->data['order_id'], $this->config->get('pagseguro_awaiting_order_id'), '');

    }

    /**
     * Link for redirect PagSeguro
     */

    private function _action()

    {


        if (!empty($this->_urlPagSeguro)) {

            return $this->config->get('config_ssl') . "index.php?route=payment/pagseguro_redirect&url_ps=" . $this->_urlPagSeguro;

        }

    }


    /**
     * Validate if value is not null
     * @param type $value
     * @return boolean
     */

    private function _isNotNull($value)

    {


        if ($value != null && $value != "")

            return TRUE;


        return false;

    }


    /**
     * Return directory log
     */

    private function _getDirectoryLog()

    {

        $_dir = str_replace('catalog/', '', DIR_APPLICATION);

        return ($this->_isNotNull($this->config->get('pagseguro_directory')) == TRUE) ? $_dir . $this->config->get('pagseguro_directory') : null;

    }

    public function app()
    {
        parent::app();
    }

    public function validate()
    {
        return parent::validate();
    }


}
