Fórum OpenCart Brasil

Por um e-commerce livre, confiável e profissional

Suporte geral sobre problemas técnicos para OpenCart v2.x.
#59910
<?php
class ModelShippingCorreios extends Model {

// máximo valor declarado, em reais
private $valor_declarado_max = 10000;

// medida padrão de cada lado da caixa, ou seja, 200cm / 3 = 66,66... (arrendondamos esse valor). onde 200 é o máximo da soma dos lados
// cubagem máxima da caixa, ou seja, 66,66^3
private $cubagem_max = 296207.4163;

// cubagem mínima da caixa levando em conta uma medida de 16cm de cada lado da caixa.
private $cubagem_min = 4096;

// medida padrão de cada lado da caixa para grandes formatos, ou seja, 300cm / 3 = 100 onde 300 é o máximo da soma dos lados para grandes formatos
// cubagem máxima da caixa para grandes formatos, ou seja, 100^3
private $cubagem_pac_gf_max = 1000000;

// esse limite do Sedex Hoje não tem em nenhum documento dos Correios e por tentativa e erro descobri um número próximo de 52cm de cada lado
private $cubagem_sedex_hoje_max = 140608;

private $peso_max = 30; // padrão, em kg
private $peso_pac_sedex_max = 30; // em kg
private $peso_esedex_max = 15; // em kg
private $peso_sedex10_12_hoje_max = 10; // em kg

private $peso_min = 0.3; // em kg

private $nCdServico = array();
private $servicos = array();

private $url = '';

private $quote_data = array();

private $cep_destino;
private $cep_origem;

private $contrato_codigo = '';
private $contrato_senha = '';

private $mensagem_erro = array();

private $correios = array(
'SEDEX' => '40010',
'40010' => 'SEDEX',

'SEDEX Pagamento na Entrega' => '40045',
'40045' => 'SEDEX Pagamento na Entrega',

'SEDEX Pagamento na Entrega - contrato' => '40126',
'40126' => 'SEDEX Pagamento na Entrega - contrato',

'SEDEX 10' => '40215',
'40215' => 'SEDEX 10',

'SEDEX 12' => '40169',
'40169' => 'SEDEX 12',

'SEDEX Hoje' => '40290',
'40290' => 'SEDEX Hoje',

'SEDEX - contrato 1' => '40096',
'40096' => 'SEDEX - contrato 1',

'SEDEX - contrato 2' => '40436',
'40436' => 'SEDEX - contrato 2',

'SEDEX - contrato 3' => '40444',
'40444' => 'SEDEX - contrato 3',

'SEDEX - contrato 4' => '40568',
'40568' => 'SEDEX - contrato 4',

'SEDEX - contrato 5' => '40606',
'40606' => 'SEDEX - contrato 5',

'PAC' => '41106',
'41106' => 'PAC',

'PAC Pagamento na Entrega' => '41262',
'41262' => 'PAC Pagamento na Entrega',

'PAC - contrato' => '41068',
'41068' => 'PAC - contrato',

'PAC Grandes Formatos - contrato' => '41300',
'41300' => 'PAC Grandes Formatos - contrato',

'e-SEDEX' => '81019',
'81019' => 'e-SEDEX',

'e-SEDEX Prioritario' => '81027',
'81027' => 'e-SEDEX Prioritario',

'e-SEDEX Express' => '81035',
'81035' => 'e-SEDEX Express',

'e-SEDEX grupo 1' => '81868',
'81868' => 'e-SEDEX grupo 1',

'e-SEDEX grupo 2' => '81833',
'81833' => 'e-SEDEX grupo 2',

'e-SEDEX grupo 3' => '81850',
'81850' => 'e-SEDEX grupo 3'
);

private function setPesoMax($peso) {
$this->peso_max = $peso;
}

private function setCubagemMax($cubagem) {
$this->cubagem_max = $cubagem;
}

private function setServicos($servicos) {
$this->servicos = $servicos;
}

private function resetServicos() {
$this->servicos = array();
}

// função responsável pelo retorno à loja dos valores finais dos valores dos fretes
public function getQuote($address) {

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

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

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

$method_data = array();

if ($status) {

$produtos = $this->cart->getProducts();

// obtém só a parte numérica do CEP
$this->cep_origem = preg_replace ("/[^0-9]/", '', $this->config->get('correios_postcode'));
$this->cep_destino = preg_replace ("/[^0-9]/", '', $address['postcode']);

// classes de serviços agrupados conforme suas propriedades. Cada classe é uma chamada ao WebService dos Correios
$this->nCdServico['pac_sedex'] = array(
'peso_max' => $this->peso_pac_sedex_max,
'cubagem_max' => $this->cubagem_max
);
$this->nCdServico['sedex10_12_hoje'] = array(
'peso_max' => $this->peso_sedex10_12_hoje_max,
'cubagem_max' => $this->cubagem_max
);
$this->nCdServico['esedex'] = array(
'peso_max' => $this->peso_esedex_max,
'cubagem_max' => $this->cubagem_max
);
$this->nCdServico['pac_gf'] = array(
'peso_max' => $this->peso_pac_sedex_max,
'cubagem_max' => $this->cubagem_pac_gf_max
);
$this->nCdServico['sedex_hoje'] = array(
'peso_max' => $this->peso_sedex10_12_hoje_max,
'cubagem_max' => $this->cubagem_sedex_hoje_max
);

$servicos['pac_sedex'] = array();
$servicos['sedex10_12_hoje'] = array();
$servicos['esedex'] = array();
$servicos['pac_gf'] = array();
$servicos['sedex_hoje'] = array();

// serviços sem contrato
if($this->config->get('correios_' . $this->correios['PAC'])){
$servicos['pac_sedex'][] = $this->correios['PAC'];
}
if($this->config->get('correios_' . $this->correios['SEDEX'])){
$servicos['pac_sedex'][] = $this->correios['SEDEX'];
}
if($this->config->get('correios_' . $this->correios['SEDEX Pagamento na Entrega'])){
$servicos['pac_sedex'][] = $this->correios['SEDEX Pagamento na Entrega'];
}
if($this->config->get('correios_' . $this->correios['PAC Pagamento na Entrega'])){
$servicos['pac_sedex'][] = $this->correios['PAC Pagamento na Entrega'];
}
if($this->config->get('correios_' . $this->correios['SEDEX 10'])){
$servicos['sedex10_12_hoje'][]= $this->correios['SEDEX 10'];
}
if($this->config->get('correios_' . $this->correios['SEDEX Hoje'])){
$servicos['sedex_hoje'][]= $this->correios['SEDEX Hoje'];
}
if($this->config->get('correios_' . $this->correios['SEDEX 12'])){
$servicos['sedex10_12_hoje'][] = $this->correios['SEDEX 12'];
}
// serviços com contrato
if(trim($this->config->get('correios_contrato_codigo')) != "" && trim($this->config->get('correios_contrato_senha')) != ""){
$this->contrato_codigo = $this->config->get('correios_contrato_codigo');
$this->contrato_senha = $this->config->get('correios_contrato_senha');

if($this->config->get('correios_' . $this->correios['SEDEX Pagamento na Entrega - contrato'])){
$servicos['pac_sedex'][] = $this->correios['SEDEX Pagamento na Entrega - contrato'];
}
if($this->config->get('correios_' . $this->correios['SEDEX - contrato 1'])){
$servicos['pac_sedex'][] = $this->correios['SEDEX - contrato 1'];
}
if($this->config->get('correios_' . $this->correios['SEDEX - contrato 2'])){
$servicos['pac_sedex'][] = $this->correios['SEDEX - contrato 2'];
}
if($this->config->get('correios_' . $this->correios['SEDEX - contrato 3'])){
$servicos['pac_sedex'][] = $this->correios['SEDEX - contrato 3'];
}
if($this->config->get('correios_' . $this->correios['SEDEX - contrato 4'])){
$servicos['pac_sedex'][] = $this->correios['SEDEX - contrato 4'];
}
if($this->config->get('correios_' . $this->correios['SEDEX - contrato 5'])){
$servicos['pac_sedex'][] = $this->correios['SEDEX - contrato 5'];
}
if($this->config->get('correios_' . $this->correios['PAC - contrato'])){
$servicos['pac_sedex'][] = $this->correios['PAC - contrato'];
}
if($this->config->get('correios_' . $this->correios['e-SEDEX'])){
$servicos['esedex'][] = $this->correios['e-SEDEX'];
}
if($this->config->get('correios_' . $this->correios['e-SEDEX Prioritario'])){
$servicos['esedex'][] = $this->correios['e-SEDEX Prioritario'];
}
if($this->config->get('correios_' . $this->correios['e-SEDEX Express'])){
$servicos['esedex'][] = $this->correios['e-SEDEX Express'];
}
if($this->config->get('correios_' . $this->correios['e-SEDEX grupo 1'])){
$servicos['esedex'][] = $this->correios['e-SEDEX grupo 1'];
}
if($this->config->get('correios_' . $this->correios['e-SEDEX grupo 2'])){
$servicos['esedex'][] = $this->correios['e-SEDEX grupo 2'];
}
if($this->config->get('correios_' . $this->correios['e-SEDEX grupo 3'])){
$servicos['esedex'][] = $this->correios['e-SEDEX grupo 3'];
}
if($this->config->get('correios_' . $this->correios['PAC Grandes Formatos - contrato'])){
$servicos['pac_gf'][] = $this->correios['PAC Grandes Formatos - contrato'];
}
}

foreach($this->nCdServico as $classe => $info){

$this->setPesoMax($info['peso_max']);
$this->setCubagemMax($info['cubagem_max']);
$this->setServicos($servicos[$classe]);

$caixas = $this->organizarEmCaixas($produtos);

// descomente a linha abaixo para visualizar em arquivos as caixas
// file_put_contents('filename' . $classe . '.txt', print_r($caixas, true));

foreach ($caixas as $caixa) {
$this->setQuoteData($caixa);
}

$this->resetServicos();
}

// ajustes finais
if ($this->quote_data) {
$total_compra = $this->cart->getSubTotal();

$valor_adicional = (is_numeric($this->config->get('correios_adicional'))) ? $this->config->get('correios_adicional') : 0 ;

foreach ($this->quote_data as $codigo => $data) {

// soma o valor adicional ao valor final do frete - não aplicado serviços de pagamento na entrega
if($codigo != $this->correios['SEDEX Pagamento na Entrega'] || $codigo != $this->correios['SEDEX Pagamento na Entrega - contrato'] || $codigo != $this->correios['PAC Pagamento na Entrega']) {

$new_cost = $this->quote_data[$codigo]['cost'] + ($this->quote_data[$codigo]['cost'] * ($valor_adicional/100));
// novo custo
$this->quote_data[$codigo]['cost'] = $new_cost;
// novo texto
$this->quote_data[$codigo]['text'] = $this->currency->format($this->tax->calculate($new_cost, $this->config->get('correios_tax_class_id'), $this->config->get('config_tax')));
}
else{
// zera o valor do frete do serviço de pagamento na entrega para evitar de ser adiconado ao valor do carrinho
$this->quote_data[$codigo]['cost'] = 0;
}
// frete grátis
if(trim($this->config->get('correios_total_' . $codigo)) != "" && $total_compra >= $this->config->get('correios_total_' . $codigo)) {
// zera o valor
$this->quote_data[$codigo]['cost'] = 0;
// novo texto
$this->quote_data[$codigo]['text'] = $this->language->get('text_free');
}

}
$method_data = array(
'code' => 'correios',
'title' => $this->language->get('text_title'),
'quote' => $this->quote_data,
'sort_order' => $this->config->get('correios_sort_order'),
'error' => false
);
}
else if(!empty($this->mensagem_erro)){
$method_data = array(
'code' => 'correios',
'title' => $this->language->get('text_title'),
'quote' => $this->quote_data,
'sort_order' => $this->config->get('correios_sort_order'),
'error' => implode('<br />', $this->mensagem_erro)
);
}
}
return $method_data;
}

// obtém os dados dos fretes para os produtos da caixa
private function setQuoteData($caixa){

// obtém o valor total da caixa
$total_caixa = $this->getTotalCaixa($caixa['produtos']);
$total_caixa = ($total_caixa > $this->valor_declarado_max) ? $this->valor_declarado_max : $total_caixa;

// fazendo a chamada ao site dos Correios e obtendo os dados
$servicos = $this->getServicos($total_caixa, $caixa['peso'], $caixa['cubagem']);

foreach ($servicos as $servico) {

// o site dos Correios retornou os dados sem erros.
$valor_frete_sem_adicionais = $servico['Valor'] - $servico['ValorAvisoRecebimento'] - $servico['ValorMaoPropria'] - $servico['ValorValorDeclarado'];
//if($servico['Erro'] == 0 && $valor_frete_sem_adicionais > 0) {
if($valor_frete_sem_adicionais > 0) {

// subtrai do valor do frete as opções desabilitadas nas configurações do módulo - 'declarar valor' é obrigatório para Sedex e PAC Pagamento na Entrega
$cost = ($this->config->get('correios_declarar_valor') == 'n' && ($servico['Codigo'] != $this->correios['SEDEX Pagamento na Entrega'] || $servico['Codigo'] != $this->correios['SEDEX Pagamento na Entrega - contrato'] || $servico['Codigo'] != $this->correios['PAC Pagamento na Entrega'])) ? ($servico['Valor'] - $servico['ValorValorDeclarado']) : $servico['Valor'];
$cost = ($this->config->get('correios_aviso_recebimento') == 'n') ? ($cost - $servico['ValorAvisoRecebimento']) : $cost;
$cost = ($this->config->get('correios_mao_propria') == 'n') ? ($cost - $servico['ValorMaoPropria']) : $cost;

// o valor do frete para a caixa atual é somado ao valor total já calculado para outras caixas
if (isset($this->quote_data[$servico['Codigo']])) {
$cost += $this->quote_data[$servico['Codigo']]['cost'];
}

$title = sprintf($this->language->get('text_'.$servico['Codigo']), $servico['PrazoEntrega']);
$text = $this->currency->format($this->tax->calculate($cost, $this->config->get('correios_tax_class_id'), $this->config->get('config_tax')));

$this->quote_data[$servico['Codigo']] = array(
'code' => 'correios.' . $servico['Codigo'],
'title' => $title,
'cost' => $cost,
'tax_class_id' => $this->config->get('correios_tax_class_id'),
'text' => $text
);
}
// grava no log de erros do OpenCart a mensagem de erro retornado pelos Correios
else{
$this->mensagem_erro[] = $this->correios[$servico['Codigo']].': ' . $servico['MsgErro'];
$this->log->write($this->correios[$servico['Codigo']].': ' . $servico['MsgErro']);
}
}
}

// prepara a url de chamada ao site dos Correios
private function setUrl($peso, $valor, $medida_lados){

$url = "http://ws.correios.com.br/calculador/Ca ... Prazo.aspx?";
//$url = "http://ws.correios.com.br/calculador/Ca ... PrecoPrazo?"; // url alternativa disponibilizada pelos Correios.
$url .= "nCdEmpresa=" . $this->contrato_codigo;
$url .= "&sDsSenha=" . $this->contrato_senha;
$url .= "&sCepOrigem=%s";
$url .= "&sCepDestino=%s";
$url .= "&nVlPeso=%s";
$url .= "&nCdFormato=1";
$url .= "&nVlComprimento=%s";
$url .= "&nVlLargura=%s";
$url .= "&nVlAltura=%s";
$url .= "&sCdMaoPropria=s";
$url .= "&nVlValorDeclarado=%s";
$url .= "&sCdAvisoRecebimento=s";
$url .= "&nCdServico=" . implode(',', $this->servicos);
$url .= "&nVlDiametro=0";
$url .= "&StrRetorno=xml";

$this->url = sprintf($url, $this->cep_origem, $this->cep_destino, $peso, $medida_lados, $medida_lados, $medida_lados, $valor);
}

// conecta ao sites dos Correios e obtém o arquivo XML com os dados do frete
private function getXML($url){

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);

$result = curl_exec($ch);

if(!$result){
$this->log->write(curl_error($ch));
$this->log->write($this->language->get('error_conexao'));
$result = curl_exec($ch);

if($result){
$this->log->write($this->language->get('text_sucesso'));
}
else{
$this->log->write(curl_error($ch));
$this->log->write($this->language->get('error_reconexao'));
}
}

curl_close($ch);

$result = str_replace('&lt;sup&gt;&amp;reg;&lt;/sup&gt;', '', $result);
$result = str_replace('&lt;sup&gt;&amp;trade;&lt;/sup&gt;', '', $result);
$result = str_replace('**', '', $result);
$result = str_replace("\r\n", '', $result);
$result = str_replace('\"', '"', $result);

return $result;
}

// faz a chamada e lê os dados no arquivo XML retornado pelos Correios
public function getServicos($total_caixa, $peso, $cubagem){

$dados = array();

// troca o separador decimal de ponto para vírgula nos dados a serem enviados para os Correios
$peso = ($peso >= $this->peso_min) ? $peso : $this->peso_min;
$peso = str_replace('.', ',', $peso);

// total é arredondado pois algumas vezes o WebService dos Correios não aceita centavos
$valor = round($total_caixa);

// medida dos lados da caixa é a raiz cúbica da cubagem
$medida_lados = ($cubagem >= $this->cubagem_min) ? $this->raizCubica($cubagem) : $this->raizCubica($this->cubagem_min);
$medida_lados = str_replace('.', ',', $medida_lados);

// ajusta a url de chamada
$this->setUrl($peso, $valor, $medida_lados);

// habilite pra ver no log de erros a url com todos os parâmetros enviados para os Correios.
// $this->log->write($this->url);

// faz a chamada e retorna o xml com os dados
$xml = $this->getXML($this->url);

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

$servicos = $dom->getElementsByTagName('cServico');

if ($servicos) {

// obtendo o prazo adicional a ser somado com o dos Correios
$prazo_adicional = (is_numeric($this->config->get('correios_prazo_adicional'))) ? $this->config->get('correios_prazo_adicional') : 0 ;

foreach ($servicos as $servico) {
$codigo = $servico->getElementsByTagName('Codigo')->item(0)->nodeValue;
// Sedex 10, 12 e Sedex Hoje não tem prazo adicional
$prazo = ($codigo == $this->correios['SEDEX 10'] || $codigo == $this->correios['SEDEX Hoje'] || $codigo == $this->correios['SEDEX 12']) ? 0 : $prazo_adicional;

$dados[$codigo] = array(
"Codigo" => $codigo,
"Valor" => str_replace(',', '.', $servico->getElementsByTagName('Valor')->item(0)->nodeValue),
"PrazoEntrega" => ($servico->getElementsByTagName('PrazoEntrega')->item(0)->nodeValue + $prazo),
"Erro" => $servico->getElementsByTagName('Erro')->item(0)->nodeValue,
"MsgErro" => $servico->getElementsByTagName('MsgErro')->item(0)->nodeValue,
"ValorMaoPropria" => (isset($servico->getElementsByTagName('ValorMaoPropria')->item(0)->nodeValue)) ? str_replace(',', '.', $servico->getElementsByTagName('ValorMaoPropria')->item(0)->nodeValue) : 0,
"ValorAvisoRecebimento" => (isset($servico->getElementsByTagName('ValorAvisoRecebimento')->item(0)->nodeValue)) ? str_replace(',', '.', $servico->getElementsByTagName('ValorAvisoRecebimento')->item(0)->nodeValue) : 0,
"ValorValorDeclarado" => (isset($servico->getElementsByTagName('ValorValorDeclarado')->item(0)->nodeValue)) ? str_replace(',', '.', $servico->getElementsByTagName('ValorValorDeclarado')->item(0)->nodeValue) : 0
);
}
}
}
return $dados;
}

// retorna a dimensão em centímetros
private function getDimensaoEmCm($unidade_id, $dimensao){

if(is_numeric($dimensao)){
$length_class_product_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "length_class mc LEFT JOIN " . DB_PREFIX . "length_class_description mcd ON (mc.length_class_id = mcd.length_class_id) WHERE mcd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND mc.length_class_id = '" . (int)$unidade_id . "'");

if(isset($length_class_product_query->row['unit'])){
if($length_class_product_query->row['unit'] == 'mm'){
return $dimensao / 10;
}
}
}
return $dimensao;
}

// retorna o peso em quilogramas
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;
}

// pré-validação das dimensões e peso do produto
private function validar($produto){

$cubagem = (float)$produto['height'] * (float)$produto['width'] * (float)$produto['length'];
$peso = (float)$produto['weight'];

if(!$peso || $peso > $this->peso_max || !$cubagem || $cubagem > $this->cubagem_max){
$this->log->write(sprintf($this->language->get('error_limites'), $produto['name']));

return false;
}

return true;
}

// 'empacota' os produtos do carrinho em caixas conforme peso, cubagem e dimensões limites dos Correios
private function organizarEmCaixas($produtos) {

$caixas = array();

foreach ($produtos as $prod) {

$prod_copy = $prod;

// muda-se a quantidade do produto para incrementá-la em cada caixa
$prod_copy['quantity'] = 1;

// todas as dimensões da caixa serão em cm e kg
$prod_copy['width'] = $this->getDimensaoEmCm($prod_copy['length_class_id'], $prod_copy['width']);
$prod_copy['height']= $this->getDimensaoEmCm($prod_copy['length_class_id'], $prod_copy['height']);
$prod_copy['length']= $this->getDimensaoEmCm($prod_copy['length_class_id'], $prod_copy['length']);

// O peso do produto não é unitário como a dimensão. É multiplicado pela quantidade. Se quisermos o peso unitário, teremos que dividir pela quantidade.
$prod_copy['weight']= $this->getPesoEmKg($prod_copy['weight_class_id'], $prod_copy['weight'])/$prod['quantity'];

$prod_copy['length_class_id'] = $this->config->get('config_length_class_id');
$prod_copy['weight_class_id'] = $this->config->get('config_weight_class_id');

$cx_num = 0;

for ($i = 1; $i <= $prod['quantity']; $i++) {

// valida as dimensões do produto com as dos Correios
if ($this->validar($prod_copy)){

// cria-se a caixa caso ela não exista.
isset($caixas[$cx_num]['peso']) ? true : $caixas[$cx_num]['peso'] = 0;
isset($caixas[$cx_num]['cubagem']) ? true : $caixas[$cx_num]['cubagem'] = 0;

$peso = $caixas[$cx_num]['peso'] + $prod_copy['weight'];
$cubagem = $caixas[$cx_num]['cubagem'] + ($prod_copy['width'] * $prod_copy['height'] * $prod_copy['length']);

$peso_dentro_limite = ($peso <= $this->peso_max);
$cubagem_dentro_limite = ($cubagem <= $this->cubagem_max);

// o produto dentro do peso e dimensões estabelecidos pelos Correios
if ($peso_dentro_limite && $cubagem_dentro_limite) {

// já existe o mesmo produto na caixa, assim incrementa-se a sua quantidade
if (isset($caixas[$cx_num]['produtos'][$prod_copy['key']])) {
$caixas[$cx_num]['produtos'][$prod_copy['key']]['quantity']++;
}
// adiciona o novo produto
else {
$caixas[$cx_num]['produtos'][$prod_copy['key']] = $prod_copy;
}

$caixas[$cx_num]['peso'] = $peso;
$caixas[$cx_num]['cubagem'] = $cubagem;
}
// tenta adicionar o produto que não coube em uma nova caixa
else{
$cx_num++;
$i--;
}
}
// produto não tem as dimensões/peso válidos então abandona sem calcular o frete.
else {
$caixas = array();
break 2; // sai dos dois foreach
}
}
}
return $caixas;
}
// retorna o valor total dos produtos na caixa
private function getTotalCaixa($products) {
$total = 0;

foreach ($products as $product) {
$total += $this->currency->format($this->tax->calculate($product['total'], $product['tax_class_id'], $this->config->get('config_tax')), '', '', false);
}
return $total;
}

private function raizCubica($n) {
return pow($n, 1/3);
}
}
?>
#59976
Consegui solucionar o meu problema.
Estava sempre dando cerca de R$ 9,00 mais caro porque estava sendo cobrado taxas de Mão própria e Aviso de recebimento.
Ao verificar as configurações dos Correios em meu site, percebi que estes dois serviços opcionais não estavam marcados, nem em sim, nem em não.
Marquei estes dois serviços em não, e o problema foi resolvido.
#60348
Limitação de compra de volume grande.

Tenho a seguinte situação:

1un do "Produto X" , tem 100x20x50cm. Comprando 1un o cliente consegue calcular o frete normal pelos correios. Mas comprando 10un nao.
Isto não pode ser limitado no modulo. Sabe Por que? Eu sei que os correios tem limite de volume e peso, mas eu vou dividir os volumes conforme os limites, só que esta divisão será feita pelo meu pessoal do estoque na hora de embalar, ela nao pode ser feita na loja ou estarei limitando a quantidade que o cliente quer. Tenho que deixar o cliente comprar o quanto ele precisar.

Só que usando os modulos de correios que temos atualmente disponiveis em opencart.com , nao conseguimos calcular frete se o cliente comprar mais de 1un de um item com tamanho um pouco grande (mas que uma "Un" nao ultrapasse as medidas limites).

Alguem sabe qual valor eu altero (cubagem max) no código php do módulo para remover a limitação. assim o volume total do pedido será contabilizado na hora de cobrar, o cliente conseguira fazer seu pedido. e o pessoal do estoque na hora de embalar é quem vai dividir o pedido em volumes menores para que seja possivel a postagem. mesmo que sejam feitas quantas postagens forem necessárias para o mesmo destinatario.

Da maneira como funciona atualmente, nao se consegue finalizar um pedido com varios itens. ex.; se o cliente compra 10 un. se for o caso eu faço 10 pacotes para serem postados.

Ou se alguem sabe de alguma extenssão que verifique a cubagem do produto (unitario) e calcule o preço do frete de forma individual para cada UN de cada produto? Assim somando todos valores ao total dos preços dos produtos no pedido.

Mas na logistica da empresa será dividido para envio. No site o cliente vai fazer o pedido normalmente, receber o custo de frete embutido no preço final.
#60959
Ae galera. Preciso de um freela para me ajudar na configuração de minha loja virtual. Tenho problemas no modulo de fretes também. Além disso, queria colocar uma busca por CEP ou EMAIL nos pedidos.... e colocar CPF e NÚMERO no cadastro, com campos obrigatórios. São alterações que acredito que sejam simples, mas não manjo nada de programação. Alguém? Meu skype é mauricio_4cores ou podem me enviar um email no mauricio@4corescomunicacao.com.br