Webservice Consulta de Frete JAMEF

Quem já precisou integrar a consulta de frete da transportadora JAMEF se deparou com o problema de não retornar o prazo de entrega. Eis a solução. Ao criar esse conexão também montei o código para trazer o prazo de entrega.

Um detalhe importante é quanto ao tempo de processamento, o servidor da JAMEF demora para responder e isso pode tornar a consulta mais lenta que encontrado em outros webservices.

consultajamef.php

<?php
class JamefConsultaFrete
{
	/* ATRIBUTOS */
	private $wsdlSchema    = 'http://';
	private $wsdlSock      = 'http://';
	private $wsdlHost      = 'www.jamef.com.br';
	private $wsdlQuery     = '/internet/e-comerce/calculafrete.asp?';
	private $trackQuery    = '/internet/e-comerce/calculafrete_xml.asp?';
	private $wsdlPort      = 80;
	private $function      = '';
	private $soapAction    = '';
	private $error         = false;

	//Login
	private $username      = ‘[CNPJ DA EMPRESA]’;
	private $_services     = array(
				'R' => array('name'  => 'Transportadora Jamef', 'title' => 'Encomenda Rodoviario',  'code' => '54'), 	//Rodoviario								'A' => array('name'  => 'Transportadora Jamef', 'title' => 'Encomenda Aereo',		'code' => '55'), 	//Aereo									);
	//Config.
	private $zipcodeSRC    = ‘[CEP_ORIGEM]’;
	private $zipcodeDST    = ‘[CEP_DESTINO]’;
	private $ufDST         = ‘[UF_DESTINO]’;
	private $cityDST       = ‘[CIDADE_DESTINO]’;
	private $width         = 0.00;			//Largura
	private $length        = 0.00;			//Comprimento
	private $height	       = 0.00;			//Altura
	private $diameter      = 0.00;			//Diametro
	private $weight        = 0.00;			//Peso
	private $price         = 0.00;			//Valor Declarado
	//Serviços
	private $ndocSRC       = array(			//Documento do Destinatário
			174 => array('name' => 'AJU', 'title' => '(Filial Aracajú)',     'uf' => 'SE'),
			122 => array('name' => 'BAR', 'title' => '(Filial Barueri)',     'uf' => 'SP'),
			111 => array('name' => 'BAU', 'title' => '(Filial Bauru)',     'uf' => 'SP'),
			1   => array('name' => 'BHZ', 'title' => '(Filial Belo Horizonte)',     'uf' => 'MG'),
			13  => array('name' => 'BNU', 'title' => '(Filial Blumenau)',     'uf' => 'SC'),
			163 => array('name' => 'BSB', 'title' => '(Filial Brasilia)',     'uf' => 'DF'),
			160 => array('name' => 'CCM', 'title' => '(Filial Criciuma)',     'uf' => 'SC'),
			12  => array('name' => 'CPQ', 'title' => '(Filial Campinas)',     'uf' => 'SP'),
			5   => array('name' => 'CXJ', 'title' => '(Filial Caxias do Sul)',     'uf' => 'RS'),
			10  => array('name' => 'CWB', 'title' => '(Filial Curitiba)',     'uf' => 'PR'),
			192 => array('name' => 'FES', 'title' => '(Filial Feira de Santana)',     'uf' => 'BA'),
			11  => array('name' => 'FLN', 'title' => '(Filial Florianópolis)',     'uf' => 'SC'),
			177 => array('name' => 'FOR', 'title' => '(Filial Fortaleza)',     'uf' => 'CE'),
			148 => array('name' => 'GYN', 'title' => '(Filial Goiânia)',     'uf' => 'GO'),
			193 => array('name' => 'ITJ', 'title' => '(Filial Itajaí)',     'uf' => 'SC'),
			4   => array('name' => 'JAS', 'title' => '(Filial Jaraguá do Sul)',     'uf' => 'SC'),
			9   => array('name' => 'JOI', 'title' => '(Filial Joinville)',     'uf' => 'SC'),
			8   => array('name' => 'LDB', 'title' => '(Filial Londrina)',     'uf' => 'PR'),
			149 => array('name' => 'MAO', 'title' => '(Filial Manaus)',     'uf' => 'AM'),
			183 => array('name' => 'MCZ', 'title' => '(Filial Maceió)',     'uf' => 'AL'),
			14  => array('name' => 'POA', 'title' => '(Filial Porto Alegre)',     'uf' => 'RS'),
			159 => array('name' => 'PSA', 'title' => '(Filial Pouso Alegre)',     'uf' => 'RS'),
			121 => array('name' => 'RAO', 'title' => '(Filial Ribeirão Preto)',     'uf' => 'SP'),
			171 => array('name' => 'REC', 'title' => '(Filial Recife)',     'uf' => 'PE'),
			3   => array('name' => 'RIO', 'title' => '(Filial Rio de Janeiro)',     'uf' => 'RJ'),
			2   => array('name' => 'SAO', 'title' => '(Filial São Paulo)',     'uf' => 'SP'),
			125 => array('name' => 'SJK', 'title' => '(Filial São José dos Campos',     'uf' => 'SP'),
			124 => array('name' => 'SJP', 'title' => '(Filial São José do Rio Preto)',     'uf' => 'SP'),
			168 => array('name' => 'SSA', 'title' => '(Filial Salvador)',     'uf' => 'BA'),
			109 => array('name' => 'UDI', 'title' => '(Filial Uberlândia)',     'uf' => 'MG'),
			7   => array('name' => 'VIX', 'title' => '(Filial Vitória)',     'uf' => 'ES')	
								  );
	private $company       = [CODIGO_FILIAL_JAMEF];		//Empresa
	private $volume	       = 1;				//Quantidade de Volume	
	//Adicionais
	private $cost 	       = 0.00;				//AdValore
	private $timeProcedure = 1;				//Tempo Minimo
	private $weightAdd     = 0.00;				//Kg adicional

	//Dados
	private $_data         = array();			//Registro - retorno da Jamef

	/* CONSTRUTOR */
	public function __construct($username, $src_zipcode, $dst_zipcode, $dst_city, $dst_uf, $company)
	{
		//Limpa os vetores de dados.
		$this->reset();

		$this->setUsername($username);
		$this->setCompany($company);

		$this->setZipcodeSRC($src_zipcode);
		$this->setZipcodeDST($dst_zipcode);
		$this->setCityDST($dst_city);
		$this->setUFDST($dst_uf);

	}

	public function setObject($width=0.00, $length=0.00, $height=0.00, $diameter=0.00, $weight=0.00, $price=0.00,$volume=1)
	{
		$this->setWidth($width);
		$this->setLength($length);
		$this->setHeight($height);
		$this->setDiameter($diameter);
		$this->setWeight($weight);
		$this->setPrice($price);
		$this->setVolume($volume);

		return $this;
	}	

	/* METODOS */
	private function getUsername()
	{
		return $this->username;
	}
	private function getPassword()
	{
		return $this->password;
	}

	private function getCompany()
	{
		return $this->company;
	}
	private function setCompany($org_id)
	{
		if ($org_id > 0) $this->company = $org_id;
	}
	private function getWsdlSchema()
	{
		return $this->wsdlSchema;
	}
	private function getWsdlSock()
	{
		return $this->wsdlSock;
	}
	private function getWsdlHost()
	{
		return $this->wsdlHost;
	}
	private function getWsdlPort()
	{
		return $this->wsdlPort;
	}
	private function getWsdlQuery()
	{
		return $this->wsdlQuery;
	}
	private function getFunction()
	{
		return $this->function;
	}
	private function getSoapAction()
	{
		return $this->soapAction;
	}
	private function getWsdl()
	{
		return $this->getWsdlSchema().$this->getWsdlHost().$this->getWsdlQuery();
	}

	private function getTracking()
	{
		return $this->getWsdlSchema().$this->getWsdlHost().$this->trackQuery;
	}

	private function checkConnect()
	{
		$fp = @fsockopen($this->getWsdlHost(), $this->getWsdlPort(), $errno, $errstr, 3);	
		if (is_resource($fp))
		{
			@fclose($fp);
			return true;			
		}
		return false;		
	}

	private function setZipcodeSRC($zipcode)
	{
		$zipcode = str_replace(array('(', ')', '-', '.', ' '), '', $zipcode);

		if (is_numeric($zipcode) & strlen($zipcode) == 8)
		{
			$this->zipcodeSRC = $zipcode;
			return true;
		}		
		return false;
	}
	private function getZipcodeSRC()
	{
		return $this->zipcodeSRC;
	}

	private function setZipcodeDST($zipcode)
	{
		$zipcode = str_replace(array('(', ')', '-', '.', ' '), '', $zipcode);

		if (is_numeric($zipcode) & strlen($zipcode) == 8)
		{
			$this->zipcodeDST = $zipcode;
			return true;
		}		
		return false;
	}	
	private function getZipcodeDST()
	{
		return $this->zipcodeDST;
	}

	private function setUFDST($uf)
	{
		if (strlen($uf) == 2)
		{
			$this->ufDST = $uf;
			return true;
		}		
		return false;
	}	
	private function getUFDST()
	{
		return $this->ufDST;
	}

	private function setCityDST($city)
	{
		$this->cityDST = $city;
	}	
	private function getCityDST()
	{
		return $this->city;
	}

	private function setWeight($weight)
	{
		$weight = doubleval($weight);
		if (is_double($weight))
		{
			$this->weight = $weight;		
			return true;
		}
		return false;
	}
	private function getWeight()
	{
		return ($this->weight + $this->getWeightAdd()) * 1;	//peso deve ser informado em Kilograma.
	}
	private function getWeightAdd()
	{
		return $this->weightAdd;
	}

	private function setDiameter($diameter)
	{
		$diameter = doubleval($diameter);
		if (is_double($diameter))
		{
			$this->diameter = $diameter/100;		
			return true;
		}
		return false;
	}
	private function getDiameter()
	{
		return $this->diameter;
	}

	private function setWidth($width)
	{
		$width = doubleval($width);
		if (is_double($width))
		{
			$this->width = $width/100;		
			return true;
		}
		return false;
	}
	private function getWidth()
	{
		return $this->width;
	}

	private function setLength($length)
	{
		$length = doubleval($length);
		if (is_double($length))
		{
			$this->length = $length/100;
			return true;
		}
		return false;
	}
	public function getLength()
	{
		return $this->length;
	}

	private function setHeight($height)
	{
		$height = doubleval($height);
		if (is_double($height))
		{
			$this->height = $height/100;
			return true;
		}
		return false;
	}
	private function getHeight()
	{
		return $this->height;
	}

	private function setPrice($price)
	{
		$price = doubleval($price);
		if (is_double($price))
		{
			$this->price = $price;
			return true;
		}
		return false;
	}
	private function getPrice()
	{
		return $this->price;
	}

	private function getCost()
	{
		return $this->cost;
	}

	private function getTimeProcedure()
	{
		return $this->timeProcedure;
	}

	private function reset()
	{
		$this->width     = 0.00;		//Largura
		$this->length    = 0.00;		//Comprimento
		$this->height	 = 0.00;		//Altura
		$this->diameter  = 0.00;		//Diametro
		$this->weight    = 0.00;		//Peso
		$this->price     = 0.00;		//Valor Declarado
	}

	private function getServicesId($code)
	{
		$_services = $this->_services;
		$name      = $_services[$code]['code'];	
		return $name; //JAMEF		
	}

	private function getNDocSRC()
	{
		return $this->ndocSRC[$this->getCompany()];
	}

	private function getVolume()
	{
		return $this->volume;
	}
	private function setVolume($volume)
	{
		if ($volume <= 0) $volume = 1;		 		$this->volume = $volume;
	}

	private function getServicesName($code)
	{
		$_services = $this->_services;
		$name      = $_services[$code]['name'];		
		return $name;
	}

	private function getServicesTitle($code)
	{
		$_services = $this->_services;
		$name      = $_services[$code]['title'];		
		return $name;
	}

	private function getConnect()
	{
		$wsdl   = $this->getWsdl();
		$client = new soap_client($wsdl, true); // true = sem namespace
		//$client = new nusoap_client($wsdl, 'wsdl'); // true = sem namespace
		$client->soap_defencoding = 'UTF-8'; 

		return $client;
	}

	private function curl_post($url, $fields)
	{
		//open connection
		$ch = curl_init();

		//set the url, number of POST vars, POST data
		curl_setopt($ch,CURLOPT_URL, $url);
		curl_setopt($ch,CURLOPT_POST, count($fields));
		curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);

		//execute post
		$result = curl_exec($ch);

		//close connection
		curl_close($ch);

		return $result;
	}

	public function getDeliveryDB($city, $uf)
	{
		$time = 7;
		if ($city != '' & $uf != '')
		{
			$l_date = date('d/m/Y');
			$url    = 'http://www.jamef.com.br/jamef/previsao_entrega.do';
			$data   = '?x=x&calcula=x&txtUf_orig=PR&txtMum_orig=LONDRINA&txtDataEmbarque='.$l_date.'&txtUf_dest='.$uf.'&txtMum_dest='.$city.'&=&';
			$result = $this->curl_post($url, $data);
			$result = str_replace("'", '"', str_replace(array("{'array':[", "]}"), "", trim($result)));
			$result = json_decode($result, true);
			if ($result != null)
			{
				if ($result['dataEntrega'] != '') $time   = Main::diffDate($result['dataEmbarque'], $result['dataEntrega']);					
			}
		}		
		return $time;
	}

	private function callFunction($format='CalcularFrete', $_param=array())
	{
		switch($format)
		{
			case 'CalcularFrete':
				$xml     = $this->convert($_param, 'CalcularFreteResult4’);
				$url     = $this->getTracking().$xml;	
				//echo $url; //exit();
				ini_set('allow_url_fopen', 1);		
				$_result = @file_get_contents($url);	
				if(!is_string($_result)) $error = true;
			break;
		}

		$this->error = $error;

		return $_result;
	}

	private function setParam($_param)
	{
		$xml     = $this->convert($_param, 'CalcularFreteResult2’);
	}

	private function toDecimal($value)
	{
		return number_format($value, 2, '.', '');
	}

	private function toNumber($value)
	{
		return number_format($value, 2, ',', '.');
	}

	private function toNumber2($value, $dec=2)
	{
		return number_format($value, $dec, ',', '');
	}

	private function convertDecimal($value)
	{
		$l_value = str_replace(".", "", $value);
		$l_value = str_replace(",", ".", $l_value);
		$l_value = $this->toDecimal(doubleval($l_value));

		return $l_value;
	}

	private function check()
	{
		$l_weight = $this->getWeight();
		if ($l_weight > 0)
		{
			$l_block  = $this->checkConnect();			
			return $l_block;
		}
		return false;
	}

	private function __get_days_up($code, $days)
	{
		$l_time = 0;
		switch($code)
		{
			default: 
				$l_time = 1;
				if (intval($days) >= 10)    $l_time = 3;
				elseif (intval($days) >= 5) $l_time = 2;
			break;
		}

		return $l_time;		
	}

	private function addCost($code, $price)
	{
		$l_cost  = $price;
		$l_price = $this->getPrice();		
		$v_cost  = $this->getCost();
		switch($code)
		{
			default: $l_cost = ($v_cost * $l_price) + $price; break;
		}		
		return doubleval($l_cost);
	}

	private function getDeliveryTime($time)
	{
		//Regra Padrao
		if ($time < 1) return 3;		 		return $time; 	} 	 	private function getUF() 	{ 		$_array = $this->getNDocSRC();
		return $_array['uf'];
	}

	private function convert($_param, $format='XML')
	{
		$xml     = '';
		$v_param = $_param[0];		
		if (is_array($v_param))
		{
			$i      = 0;
			$f      = sizeof($v_param);
			$v_keys = array_keys($v_param);

			switch($format)
			{
				case 'CalcularFreteResultXML’:

					$xml    = '        <'.$this->getFunction().' xmlns="http://schemas.xmlsoap.org/soap/encoding/">';
					while($i<$f)
					{
						$key   = $v_keys[$i];
						$value = $v_param[$key];

						$xml .= '		<'.$key.'>'.$value.'';
						$i++;
					}
					$xml .= 'getFunction().'>';
				break;

				case 'CalcularFreteResult’:
					while($i<$f)
					{
						$key   = $v_keys[$i];
						$value = $v_param[$key];

						$xml[] = $key.'='.$value;
						$i++;
					}

					$xml = implode(",", $xml);	
				break;

				case 'CalcularFreteResult2’:
					while($i<$f)
					{
						$key   = $v_keys[$i];
						$value = $v_param[$key];

						$xml[] = $value;
						$i++;
					}

					$xml = implode(",", $xml);	
				break;

				case 'CalcularFreteResult4’:
					while($i<$f) 					{ 						$key   = $v_keys[$i]; 						$value = $v_param[$key]; 									 						$xml[] = $key.'='.$value; 						$i++; 					} 					 					$xml = implode("&", $xml);	 				break; 			} 		} 		 		return $xml; 	} 	 	public function getData() 	{ 		$error   = false; 		$check   = $this->check();
		if ($check)
		{
			//echo $this->getWidth();
			//echo ($this->getVolume()*$this->getWidth()*$this->getHeight()*$this->getLength()); exit();
			$_param  = array (
							array (
								'P_CIC_NEGC'	      => $this->getUsername(),
								'P_COG_REGN'	      => $this->getCompany(),
								'P_CEP'		      => $this->getZipcodeDST(),
								'P_PESO_KG'    	      => $this->toNumber2($this->getWeight()),
								'P_VLR_CARG'          => $this->toNumber2($this->getPrice()),
								'P_UF'                => $this->getUF(),
								'P_CUBG'              => $this->toNumber2(($this->getWidth()*$this->getHeight()*$this->getLength()), 4)
								)
							);

			//echo '
'; print_r($_param); echo '

‘;//exit();
$_result = $this->callFunction(‘CalcularFrete, $_param);
$error = $this->error;
$_data = array();
if (!$error)
{
$data = ($_result);
$xml = new xml2array();
$_array = $xml->parse($data);
//echo ‘

';	print_r($_array);	exit();
				$_array = $_array[0]['children'][0]['children'];
				if ($_array[0]['tagData'] == '1')
				{
					$_data    = array(
								0 => 
									array(
										'Codigo'		 		=> $this->getServicesId($_array[3]['tagData']),
										'Valor' 		 		=> $_array[2]['tagData'],
										'PrazoEntrega'   		=> $this->getDeliveryDB($this->getCityDST(), $this->getUFDST()),
										'Erro' 			        => 0,
										'MsgErro'		        => '',
										'ValorMaoPropria'       => 0,
										'ValorAvisoRecebimento' => 0,
										'ValorValorDeclarado'	=> 0.00,
										'EntregaDomiciliar' 	=> 'N',
										'Seguro'			 	=> 'N',
										'EntregaSabado' 		=> 'N'
										)
									);
				}
			}

			$this->_data = $_data;			
		}
		return $this;
	}

	public function procedure()
	{
		$_data        = $this->_data;		
		$l_count      = sizeof($_data);

		if ($l_count > 0)		
		{
			$x                 = 0;	//Inicio
			while($x < $l_count) 			{ 				$l_value = $this->convertDecimal($_data[$x]['Valor']);
				$l_time1 = intval($_data[$x]['PrazoEntrega']);
				$l_code  = $_data[$x]['Codigo'];
				if ($l_code != '' & $l_value > 0.00 & $l_time1 > 0)	//Codigo com erro -1 -2 -99
				{
					$l_time = $this->getDeliveryTime($l_time1);
					$l_value= $this->convertDecimal($_data[$x]['Valor'])*0.9;

					$_data[$x]['Nome']      			 = $this->getServicesName($l_code);
					$_data[$x]['Descricao'] 			 = $this->getServicesTitle($l_code);
					$_data[$x]['ValorReal'] 			 = $l_value;
					$_data[$x]['Valor']    				 = $this->convertDecimal($this->toNumber($this->addCost($l_code, $_data[$x]['ValorReal'])));
					$_data[$x]['ValorTotal'] 			 = $this->toDecimal($_data[$x]['Valor'] + $_data[$x]['ValorMaoPropria'] + $_data[$x]['ValorAvisoRecebimento'] + $_data[$x]['ValorValorDeclarado']);
					$_data[$x]['PrazoEntregaReal'] 		 = $l_time1;
					$_data[$x]['PrazoEntrega'] 			 = ($l_time + $this->getTimeProcedure() + $this->__get_days_up($l_code, $l_time));

				}
				else unset($_data[$x]);

				$x++;
			}
		}
		else return -1;		
		return $_data;
	}
}
?>

resultado.php

<?php

$CNPJ = '';		// CNPJ da empresa
$CEP_ORIGEM = '';	// CEP da empresa
$CEP_DESTINO = '';	// CEP do destinatario
$CIDADE = '';	        // CIDADE do destinario
$UF = '';		// UF do destinario
$FILIAL_JAMEF = '';	// FILIAL da Jamef que irá fazer a coleta

$jamef = new JamefConsultaFrete($CNPJ, $CEP_ORIGEM, $CEP_DESTINO, $CIDADE, $UF, $FILIAL_JAMEF);
$jamef->setObject($largura, $comprimento, $altura, $diametro, $peso, $valor_declarado_da_nota, $qtde_volume);
$resultado = $jamef->getData()->procedure();

echo '<pre>';
print_r($resultado);
echo '</pre>';
?>