<?php

class ModelShippingTnt extends Model
{

    private $quote_data = array();

    private $user_login;
    private $ie;
    private $ie_destino;
    private $cnpj;
    private $situacao_trib;
    private $situacao_trib_destino;
    private $tipo_pessoa;
    private $tipo_pessoa_destino;
    private $cep_origem;
    private $cep_destino;
    private $tipo_servico;
    private $tipo_frete;
    private $divisao_cliente;

    private $largura;
    private $altura;
    private $peso;
    private $peso_total;
    private $valor_nf;
    private $volumes;
    private $text;

    private $tnt = array(
        'tnt' => 'tnt',
        'tnt' => 'tnt',
    );

    // função responsável pelo retorno à loja dos valores finais dos valores dos fretes

    function getQuote($address_data, $pProduct = array())
    {
        $this->load->type('tipocomum');

        // Initialize the variables
        $user_login = '';
        $ie = '0';
        $ie_destino = '0';
        $cnpj = '0';
        $situacao_trib = 'CO';
        $situacao_trib_destino = 'CO';
        $tipo_pessoa = 'J';
        $tipo_pessoa_destino = 'F';
        $cep_origem = '0';
        $cep_destino = '0';
        $tipo_servico = 'RNC';
        $tipo_frete = 'C';
        $divisao_cliente = 1;
        $largura = "";
        $altura = "";
        $peso = 0;
        $peso_total = 0;
        $valor_nf = 0;
        $volumes = 0;
        $text = "";

        $this->load->language('shipping/tnt');

        if (!$this->config->get('tnt_status')) {
            $status = FALSE;
        } else {
            //feito a principio para skyhub Frete, mais pode ser utilizado para qualquer frete que
            //não tenha informações do estado...
            if ((!$address_data['zone_id']) && ($address_data['layout_id'] == Type_SendPostcode::Tp_Product)) {
                $status = true;
            } else {
                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('tnt_geo_zone_id') . "' AND country_id = '" . (int)$address_data['country_id'] . "' AND (zone_id = '" . (int)$address_data['zone_id'] . "' OR zone_id = '0')");

                if (!$this->config->get('tnt_geo_zone_id')) {
                    $status = TRUE;
                } elseif ($query->num_rows) {
                    $status = TRUE;
                } else {
                    $status = FALSE;
                }
            }
        }

        if (!$this->customer->isLogged()) {
            return false;
        }

        $error = false;
        $method_data = array();

        if ($status) {
            try {

                $soaptimeoutini = ini_get('default_socket_timeout');
                $currency_id = $this->session->data['currency'];

                // Obtem os dados para a consulta no WebService da tnt
                ini_set('default_socket_timeout', 5);//timeout de 4 segundos pra não travar a conexão...

                $location_URL = 'https://ws.tntbrasil.com.br/tntws/CalculoFrete?wsdl';
                
                $uri = 'http://service.calculoFrete.mercurio.com';

                $client = new SoapClient(null, array(
                    'location' => $location_URL,
                    'uri'      => $uri,
                    'trace'    => 1,
                ));
                ini_set('default_socket_timeout', $soaptimeoutini);//volta o timeout do php default...
                $user_login = $this->config->get('tnt_user_login');
                $ie = preg_replace('/[^\d\s]/', '', $this->config->get('tnt_ie'));
                $cnpj = preg_replace('/[^\d\s]/', '', $this->config->get('tnt_cnpj'));
                $situacao_trib = $this->config->get('tnt_situacao_trib');
                $tipo_pessoa = $this->config->get('tnt_tipo_pessoa');
                $cep_origem = preg_replace('/[^\d\s]/', '', $this->config->get('tnt_postcode'));
                $tipo_servico = $this->config->get('tnt_tipo_servico');
                $tipo_frete = $this->config->get('tnt_tipo_frete');
                $divisao_cliente = $this->config->get('tnt_divisao_cliente');


                // Configura os dados especificos do cliente
                $ie_destino = $this->customer->getInscricaoEstadual();
                $tipo_pessoa_destino = $this->customer->getTipo_pessoa();

                $situacao_trib_destino = $this->customer->getContribuinte();
                if ($situacao_trib_destino == 'S') {
                    $situacao_trib_destino = 'CO';
                } else {
                    $situacao_trib_destino = 'NC';
                }

                $cep_destino = preg_replace('/[^\d\s]/', '', $address_data['postcode']);
                if ($tipo_pessoa_destino == 'J') {
                    $cpfcnpjdestino = $this->customer->getCnpj();;
                } else {
                    $cpfcnpjdestino = $this->customer->getCpf();
                }

                // Obtem os dados dos produtos
                //peso ,volumes e valor - $peso $volumes $valor_nf
                if (sizeof($pProduct) > 0) {
                    $produtos = $pProduct;
                    $volumes = 0;
                    $valor_nf = 0;
                    foreach ($produtos as $product) {
                        $valor_nf += $product['price'] * $product['quantity'];
                        $volumes += $product['quantity'];
                    }
                } else {
                    $produtos = $this->cart->getProducts();
                    $volumes = $this->cart->countProducts();
                    $valor_nf = $this->cart->getTotal();
                }
                // Calcula a cubagem (Comp x Larg x Alt x Qnt x 300)

                $tipopeso = $this->config->get('tnt_tipo_peso');
                if ($tipopeso == Type_TntPeso::Tp_Cubagem) {
                    foreach ($produtos as $prod) {
                        $peso = (($prod['length'] * 0.01) * ($prod['width'] * 0.01) * ($prod['height'] * 0.01));
                        $peso = (round($peso, 2)) * ($prod['quantity']);
                        $peso_total += $peso;
                    }
                    // Multiplica pelo fator de metro quadrado
                    $peso_total = $peso_total * 300;
                } elseif (is_array($pProduct) && sizeof($pProduct) > 0) {
                    $peso_total = current($pProduct)['weight'];
                } else {
                    $peso_total = $this->cart->getWeight();
                }

                // ===============================================
                // Webservice sem utilizacao de cubagem interna
                // ===============================================
                //$cubagem = true;
                //if($peso_total <= 90){
                //		$peso_total = $this->cart->getWeight();
                //		$cubagem = false;
                //}
                // ===============================================

                // Consulta ao WebService
                $xmlr = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.calculoFrete.mercurio.com" xmlns:mod="http://model.vendas.lms.mercurio.com">
                           <soapenv:Header/>
                           <soapenv:Body>
                              <ser:calculaFrete>
                                 <ser:in0>
                                    <mod:login>' . $user_login . '</mod:login>
                                    <mod:senha></mod:senha>
                                    <mod:nrIdentifClienteRem>' . $cnpj . '</mod:nrIdentifClienteRem>
                                    <mod:nrIdentifClienteDest>' . $cpfcnpjdestino . '</mod:nrIdentifClienteDest>
                                    <mod:tpFrete>' . $tipo_frete . '</mod:tpFrete>
                                    <mod:tpServico>' . $tipo_servico . '</mod:tpServico>
                                    <mod:cepOrigem>' . $cep_origem . '</mod:cepOrigem>
                                    <mod:cepDestino>' . $cep_destino . '</mod:cepDestino>
                                    <mod:vlMercadoria>' . number_format($valor_nf, 2, '.', '') . '</mod:vlMercadoria>
                                    <mod:psReal>' . number_format($peso_total, 3, '.', '') . '</mod:psReal>
                                    <mod:nrInscricaoEstadualRemetente>' . $ie . '</mod:nrInscricaoEstadualRemetente>
                                    <mod:nrInscricaoEstadualDestinatario>' . $ie_destino .'</mod:nrInscricaoEstadualDestinatario>
                                    <mod:tpSituacaoTributariaRemetente>' . $situacao_trib . '</mod:tpSituacaoTributariaRemetente>
                                    <mod:tpSituacaoTributariaDestinatario>'. $situacao_trib_destino .'</mod:tpSituacaoTributariaDestinatario>
                                    <mod:cdDivisaoCliente>' . $divisao_cliente . '</mod:cdDivisaoCliente>
                                    <mod:tpPessoaRemetente>' . $tipo_pessoa . '</mod:tpPessoaRemetente>
                                    <mod:tpPessoaDestinatario>' . $tipo_pessoa_destino . '</mod:tpPessoaDestinatario>
                                 </ser:in0>
                              </ser:calculaFrete>
                           </soapenv:Body>
                        </soapenv:Envelope>';

                $action_URL = 'https://ws.tntbrasil.com.br/tntws/CalculoFrete';

                $xml = $client->__doRequest($xmlr, $location_URL, $action_URL, 1);

                // Le o XML
                $dom = new DOMDocument('1.0', 'ISO-8859-1');
                $dom->loadXml($xml);

                if ($dom->getElementsByTagName('errorList')->length) {
                    $errorList = $dom->getElementsByTagName('errorList')->item(0)->nodeValue;
                } else {
                    $errorList = false;
                }

                if ($errorList) {
                    $logData = [
                        'event'    => 'getQuote_tnt',
                        'message'  => 'Error TNT',
                        'IDCliente' => $this->customer->getId(),
                        'error'    => $errorList,
                        'datetime' => date('c'), // data/hora no padrão ISO
                    ];
                    $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
                } else {

                    $municipio = $dom->getElementsByTagName('nmMunicipioDestino')->item(0)->nodeValue;
                    $vlTotalFrete = $dom->getElementsByTagName('vlTotalFrete')->item(0)->nodeValue;
                    $prazo = $dom->getElementsByTagName('prazoEntrega')->item(0)->nodeValue;

                    $title = $this->language->get('text_tnt_padrao');

                    $valor_adicional = (is_numeric($this->config->get('tnt_adicional'))) ? $this->config->get('tnt_adicional') : 0;
                    $new_cost = $vlTotalFrete + ($vlTotalFrete * ($valor_adicional / 100));

                    if (($this->config->get('tnt_prazo_adicional') !== null) && ($this->config->get('tnt_prazo_adicional') > 0)) {
                        $prazo = $prazo + $this->config->get('tnt_prazo_adicional');
                    } else {
                        $prazo = $prazo;
                    }

                    // Gera a cotação
                    if ($new_cost > 0) {
                        $this->quote_data['tnt'] = array(
                            'code' => 'tnt.tnt',
                            'title' => $title . " (Prazo de Entrega para " . $municipio . ": " . $prazo . " Dias.)",
                            'days' => $prazo,
                            'cost' => round((float)$new_cost, 2, PHP_ROUND_HALF_UP),
                            'tnt' => 'tnt',
                            'text' => $this->currency->format($new_cost, $currency_id)
                        );
                    }

                }

            } catch (Exception $e) {
                $logData = [
                    'event'    => 'getQuote_tnt',
                    'message'  => 'Error TNT',
                    'exception'=> [
                        'type'    => get_class($e),
                        'message' => $e->getMessage(),
                        'code'    => $e->getCode(),
                        'file'    => $e->getFile(),
                        'line'    => $e->getLine(),
                        'trace'   => $e->getTraceAsString()
                    ],
                    'datetime' => date('c'), // data/hora no padrão ISO
                ];
                $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
                ini_set('default_socket_timeout', $soaptimeoutini);//volta o timeout do php default...
            }

            // Gera o retorno da cotacao
            if (count($this->quote_data) > 0) {
                $method_data = array(
                    'code' => 'tnt',
                    'title' => $this->language->get('text_title'),
                    'quote' => $this->quote_data,
                    'sort_order' => $this->config->get('tnt_sort_order'),
                    'error' => false
                );

                return $method_data;
            }

        }


    }

}
