<?php
class ModelShippingTotalExpress extends Model {

	public function getQuote($address) {
		$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('totalexpress_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')");

		$url = 'https://edi.totalexpress.com.br/webservice_calculo_frete.php?wsdl';

		if (!$this->config->get('totalexpress_geo_zone_id')) {
			$status = true;
		} elseif ($query->num_rows) {
			$status = true;
		} else {
			return array();
		}

		if (!$this->config->get('totalexpress_status')) {
			return array();
		}

		$servicos = $this->config->get('totalexpress_servicos');

		if (count($servicos) == 0) {
			return array();
		}

		if (!$status) {
			return array();
		}

		$method_data = array();
		$quote_data = array();

		foreach ($servicos as $k => $v) {
			if (isset($v['status']) && $v['status'] == 1) {
				$detalhes = $this->detalhesProdutos($v['cubagem']);

				if ($detalhes['real'] > $detalhes['cubado']) {
					$peso = $detalhes['real'];
				} else {
					$peso = $detalhes['cubado'];
				}

				if ($peso < $this->config->get('totalexpress_minimo')) {
					return array();
				}

				$soap_opt = array();
				$soap_opt['stream_context'] = stream_context_create(array('http' => array('protocol_version' => 1.0) ) );
				$soap_opt['encoding']       = 'UTF-8';
				$soap_opt['trace']          = true;
				$soap_opt['exceptions']     = true;
				$soap_opt['login']          = trim($this->config->get('totalexpress_login'));
				$soap_opt['password']       = trim($this->config->get('totalexpress_senha'));

				$request = array();
				$request['TipoServico']    = strtoupper($k);
				$request['CepDestino']     = preg_replace('/\D/', '', $address['postcode']);
				$request['Peso']           = number_format($peso, 2, ',', '');
				$request['ValorDeclarado'] = number_format($this->cart->getSubTotal(), 2, ',', '');
				$request['TipoEntrega']    = 0;
				$request['ServicoCOD']     = false;

				$client = new SoapClient($url, $soap_opt);

				try {
					$info = $client->__call("calcularFrete", array($request));
					if (isset($info->CodigoProc)) {
						if ($info->CodigoProc == 1) {

							$frete = $info->DadosFrete;
							$calculo_total = (float)str_replace(',', '.', str_replace('.', '', $frete->ValorServico));
							$calculo_total += (float)$this->config->get('totalexpress_taxa_extra');
							$prazo_extra = (int)$this->config->get('totalexpress_prazo_extra');

							$quote_data[$k] = array(
								'code'         => 'totalexpress.'.$k,
								'title'        => $v['nome'].' em até '.($frete->Prazo+$prazo_extra).' dias',
								'cost'         => $this->tax->calculate($calculo_total, $this->config->get('totalexpress_tax_class_id'), $this->config->get('config_tax')),
								'tax_class_id' => $this->config->get('totalexpress_tax_class_id'),
								'text'         => $this->formatar($this->tax->calculate($calculo_total, $this->config->get('totalexpress_tax_class_id'), $this->config->get('config_tax')))
							);
						} else {
							$erro = isset($info->ErroConsultaFrete) ? $info->ErroConsultaFrete : 'Verificar login/senha e ambiente!';
							$this->log->write("Erro Total Express: {$k} {$erro}");
						}
					}
				} catch (SoapFault $fault) {
					$this->log->write("Erro Total Express: {$k} ".print_r($fault->faultstring, true)."");
				}
			}
		}

		//se retornou contas
		if (count($quote_data) > 0) {
			$method_data = array(
				'code'       => 'totalexpress',
				'title'      => $this->config->get('totalexpress_nome'),
				'quote'      => $quote_data,
				'sort_order' => $this->config->get('totalexpress_sort_order'),
				'error'      => false
			);
		}

		return $method_data;
	}

	public function formatar($valor){
		if (version_compare(VERSION, '2.2.0.0', '>=')) {
			return $this->currency->format($valor, $this->session->data['currency']);
		} else {
			return $this->currency->format($valor);
		}
	}

	public function detalhesProdutos($fator){
		$produtos = $this->cart->getProducts();
		$weight = $this->cart->getWeight();
		$peso_cubico = $peso_real = $mt3 = $volume = 0;
		//faz a cubagem dos produtos
		$fator_cubagem = ($fator > 0) ? $fator : 300;
		foreach ($produtos as $prod) {
			$lar = $this->qualMedidaProduto($prod['length_class_id'], $prod['length']);
			$alt = $this->qualMedidaProduto($prod['length_class_id'], $prod['height']);
			$com = $this->qualMedidaProduto($prod['length_class_id'], $prod['width']);
			$peso_cubico += (($lar * $com * $alt) * $fator_cubagem) * $prod['quantity'];
			$mt3 += ($lar * $com * $alt) * $prod['quantity'];
			$volume += $prod['quantity'];
		}
		return array(
			'mt3'    => $mt3,
			'real'   => $weight,
			'cubado' => number_format($peso_cubico, 2, '.', ''),
			'volume' => $volume
		);
	}

	public function qualMedidaProduto($un, $med){
		$result = $this->db->query("SELECT * FROM " . DB_PREFIX . "length_class_description WHERE length_class_id = '" . (int)$un . "' AND language_id = '" . $this->config->get('config_language_id') . "'");
		if ($result->row['unit'] == 'mm') {
			return ($med / 1000);
		} elseif ($result->row['unit'] == 'cm') {
			return ($med / 100);
		} else {
			return $med;
		}
	}

	private function getPesoEmKg($unidade_id, $peso){
		if (is_numeric($peso)) {
			$weight_class_product_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "weight_class wc LEFT JOIN " . DB_PREFIX . "weight_class_description wcd ON (wc.weight_class_id = wcd.weight_class_id) WHERE wcd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND wc.weight_class_id = '" . (int)$unidade_id . "'");

			if (isset($weight_class_product_query->row['unit'])) {
				if ($weight_class_product_query->row['unit'] == 'g') {
					return ($peso / 1000);
				}
			}
		}
		return $peso;
	}
}
