<?php
class Cart
{
    private $config;
    private $db;
    private $data = array();
    private $data_recurring = array();
    private $flag = true;
    private $load;
    private $registry;

    public function __construct($registry)
    {
        $this->config = $registry->get('config');
        $this->customer = $registry->get('customer');
        $this->session = $registry->get('session');
        $this->db = $registry->get('db');
        $this->weight = $registry->get('weight');
        $this->futuracalcularst = $registry->get('futuracalcularst');
        $this->ftrgeralregistry = new Ftr_geral_registry($registry);
        $this->load = $registry->get('load');
        $this->registry = $registry;


        if (!isset($this->session->data['cart']) || !is_array($this->session->data['cart'])) {
            $this->session->data['cart'] = array();
            $this->session->data['addQtd'] = array();
        }
    }

    public function __get($name)
    {
        return $this->registry->get($name);
    }

    public function getDescontoAcrescimo($tipo = Type_DescontoAcrescimo::Tp_Desconto, $discountkit = false)
    {
        // Totals
        $this->load->model('setting/extension');

        $total_data = array();
        $total = 0;
        $retorno = 0;

        // Display prices
        if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {
            $results = $this->model_setting_extension->getExtensions('total', Type_ExtensionSubType::Tp_TotalizadorAcrescimoDesconto);

            foreach ($results as $result) {
                if ($result['code'] != 'descontoautomatico' && $this->config->get($result['code'] . '_status') && (($result['code'] != 'descontoacrescimokit') || $discountkit)) {
                    $this->load->model('total/' . $result['code']);

                    $this->{'model_total_' . $result['code']}->getTotal($total_data, $total);
                }
            }

            foreach ($total_data as $data) {

                if (($tipo == Type_DescontoAcrescimo::Tp_Desconto) && ($data['value'] < 0)) {
                    $retorno += floatval($data['value']);
                } elseif (($tipo == Type_DescontoAcrescimo::Tp_Acrescimo) && ($data['value'] > 0)) {
                    $retorno += floatval($data['value']);
                }
            }
        }

        return ($tipo == Type_DescontoAcrescimo::Tp_Desconto) ?  $retorno * -1 : $retorno;
    }

    public function rateiaValores()
    {
        $acc_acrescimo = 0;
        $acc_desconto  = 0; /*Variaveis para controlar a sobra*/
        $acc_frete     = 0;

        $valorAcreProd = 0;
        $valorDescProd = 0;
        $valorFreteProd= 0;

        $inc = 0;
        $sequencia = 0;
        $subtotal =  0;
        $produtosAux = array();

        foreach ($this->data as $product) {
            /*
            -> É necessário fazer esse ajuste por causa do Kit de produtos,
            o rateio precisa ser feito pelos itens individualmente, desconsiderando o Kit pai,
            pois serão os items que vão replicar no pedido
            -> sequence_key não é o mesmo que $sequencia, a sequencia é necessária para recuperar
            as infos do calculo da ST e o sequence_key é a sequencia do item do kit
            */
            $acerto_total = 0;
            $total_kit    = 0;
            $acerto_desconto = 0;
            $acerto_acrescimo = 0;

            if ($product['product_kit_id']) {
                foreach ($product['itens_kit'] as $product_kit) {
                    $sequencia = $sequencia += 1;
                    $produtosAux[] = array(
                        'sequence_key' => $product_kit['sequence_key'],
                        'id_futura' => $product_kit['product_id_futura'],
                        'quantity'  => (int)$product_kit['quantidade'] * $product['quantity'],
                        'price'     => (float)$product_kit['price'],
                        'total'     => (float)$product_kit['price'] * ((int)$product_kit['quantidade'] * (int)$product['quantity']),
                        'product_kit_id' => (int)$product['product_kit_id'],
                        'id_pkit_futura' => (int)$product['id_futura'], /* ID futura do produto pai (KIT) */
                        'sequencia'      => $sequencia,
                        'acerto' => (float)$product_kit['acerto'] * $product['quantity'],
                        'key' => $product['key'],
                    );
                    $acerto_total += (float)$product_kit['acerto'] * (int)$product['quantity'];

                    if ((float)$product_kit['acerto'] > 0){
                        $acerto_acrescimo += (float)$product_kit['acerto'] * (int)$product['quantity'];
                    }else{
                        $acerto_desconto += (float)$product_kit['acerto'] * (int)$product['quantity'];
                    }

                    $total_kit += (float)$product_kit['price'] * ((int)$product_kit['quantidade'] * (int)$product['quantity']);
                }
                $this->data[$product['key']]['acerto_kit']           = $acerto_total;
                $this->data[$product['key']]['acerto_kit_desconto']  = $acerto_desconto;
                $this->data[$product['key']]['acerto_kit_acrescimo'] = $acerto_acrescimo;
                $this->data[$product['key']]['total_kit']  = $total_kit;

                $subtotal += $total_kit;
            } else {
                $sequencia = $sequencia += 1;
                $produtosAux[] = array(
                    'id_futura' => $product['id_futura'],
                    'quantity'  => $product['quantity'],
                    'price'     => $product['price'],
                    'total'     => $product['total'],
                    'cart_key'  => $product['key'],
                    'sequencia' => $sequencia,
                    'acerto' => 0,
                    'key' => $product['key']
                );
                $subtotal += $product['total'];
            }
        }
        //$subtotal = $this->getSubTotal();
        $totaldesconto  = $this->getDescontoAcrescimo(Type_DescontoAcrescimo::Tp_Desconto);
        $totalacrescimo = $this->getDescontoAcrescimo(Type_DescontoAcrescimo::Tp_Acrescimo);
        $total_dicount_kit   = round($this->getDescontoAcrescimo(Type_DescontoAcrescimo::Tp_Desconto, true), 2, PHP_ROUND_HALF_DOWN);
        $total_acrescimo_kit = round($this->getDescontoAcrescimo(Type_DescontoAcrescimo::Tp_Acrescimo, true) , 2, PHP_ROUND_HALF_DOWN);;
        $totalfrete = isset($this->session->data['shipping_method']['cost']) ? $this->session->data['shipping_method']['cost'] : 0;

        $countprod = count($produtosAux);
        foreach ($produtosAux as $produto) {
            $inc += 1;
            $baseproduto  = (($produto['quantity'] * $produto['price']) * 100) / $subtotal;

            $valorAcreProd = (($baseproduto  / 100) * $totalacrescimo) + ((isset($produto['acerto']) && $produto['acerto'] > 0) ? $produto['acerto'] : 0);
            $valorAcreProd = round($valorAcreProd, 2, PHP_ROUND_HALF_DOWN);
            $this->data[$produto['key']]['acrescimo_valor'] += $valorAcreProd;
            $this->data[$produto['key']]['acrescimo_percentual'] = ($this->data[$produto['key']]['acrescimo_valor'] * 100) / $subtotal;
            $acc_acrescimo +=  $valorAcreProd;
            if (($acc_acrescimo <> $total_acrescimo_kit) && ($countprod == $inc)) {
                $valorAcreProd += $total_acrescimo_kit - round($acc_acrescimo, 2, PHP_ROUND_HALF_DOWN);
                $this->data[$produto['key']]['acrescimo_valor'] = $valorAcreProd;
            }

            $valorDescProd = (($baseproduto  / 100) * $totaldesconto) + ((isset($produto['acerto']) && $produto['acerto'] < 0) ? $produto['acerto'] * -1 : 0);
            $valorDescProd = round($valorDescProd, 2, PHP_ROUND_HALF_DOWN);
            $this->data[$produto['key']]['desconto_valor'] += $valorDescProd;
            $this->data[$produto['key']]['desconto_percentual'] += ($this->data[$produto['key']]['desconto_valor'] * 100) / $subtotal;
            $acc_desconto +=  $valorDescProd;
            if (($acc_desconto <> $total_dicount_kit) && ($countprod == $inc)) {
                $valorDescProd += $total_dicount_kit - round($acc_desconto, 2, PHP_ROUND_HALF_DOWN);
                $this->data[$produto['key']]['desconto_valor'] = $valorDescProd;
            }

            $valorFreteProd = round( (($baseproduto / 100) * $totalfrete),2, PHP_ROUND_HALF_DOWN);
            $this->data[$produto['key']]['frete_valor'] += $valorFreteProd;
            $acc_frete +=  $valorFreteProd;
            if (($acc_frete <> $totalfrete) && ($countprod == $inc)) {
                $valorFreteProd += $totalfrete - round($acc_frete, 2, PHP_ROUND_HALF_DOWN);
                $this->data[$produto['key']]['frete_valor'] = $valorFreteProd;
            }

            if( isset($produto['sequence_key']) ){
                $key = array_search($produto['sequence_key'], array_column($this->data[$produto['key']]['itens_kit'], 'sequence_key'));
                $this->data[$produto['key']]['itens_kit'][$key]['acrescimo_valor'] = $valorAcreProd;
                $this->data[$produto['key']]['itens_kit'][$key]['acrescimo_percentual'] = ($valorAcreProd * 100) / $subtotal;;
                $this->data[$produto['key']]['itens_kit'][$key]['desconto_valor'] = $valorDescProd;
                $this->data[$produto['key']]['itens_kit'][$key]['desconto_percentual'] = ($valorDescProd * 100) / $subtotal;
                $this->data[$produto['key']]['itens_kit'][$key]['frete_valor'] = $valorFreteProd;
            }
        }

        return true;
    }

    public function getProducts()
    {   $rate = false;
        if (!$this->data) {
            $this->load->type('tipocomum');
            $this->load->helper('ftr_geral');
            $sequencia = 0;

            foreach ($this->session->data['cart'] as $key => $product_session_cart) {
                $quantity = $product_session_cart['quantity'];
                $product = explode(':', $key);
                $product_id = $product[0];
                $stock = true;

                // Options
                if (!empty($product[1])) {
                    $options = unserialize(base64_decode($product[1]));
                } else {
                    $options = array();
                }

                // Profile

                if (!empty($product[2])) {
                    $profile_id = $product[2];
                } else {
                    $profile_id = 0;
                }

                //ID da lista escolar
                if (!empty($product[3])) {
                    $lista_escolar_id = $product[3];
                } else {
                    $lista_escolar_id = 0;
                }
                $lista_escolar_descricao = isset($product_session_cart['descricao_listaescolar']) ? $product_session_cart['descricao_listaescolar'] : null;

                $data_language = $this->config->get('config_data_language');
                if (!isset($data_language) || $data_language == Type_DataLanguage::Tp_Portugues_Brasil) {
                    unset($data_language);
                }

                if ($this->config->get('futuragrade_status')) {
                    $language = $this->language->load('module/futuragrade');
                    $title_specification = (ftr_geral::isIsset($this->config->get('futuragrade_title_specification')) &&  $this->config->get('futuragrade_title_specification') != "") ? $this->config->get('futuragrade_title_specification') : $this->language->get('heading_title_specification');
                    $title_size = $this->language->get('heading_title_size');
                    $title_cor = $this->language->get('heading_title_cor');
                    $sql =
                        "SELECT"
                        . " p.*,"
                        . " pd.*,";

                    $sql .= isset($data_language) ? "coalesce(pt.descricao_ecommerce, pd.name) as name," : "";

                    $sql .= " (pc.description)  color_description,"
                        . " (ps.description)  size_description,"
                        . " (psp.description) specification_description,"
                        . "	pkit.product_kit_id AS product_kit_id,"
                        . " (COALESCE(pgt.descricao_cor,'$title_cor')) color_template_description,"
                        . " (COALESCE(pgt.descricao_tamanho,'$title_size')) size_template_description,"
                        . " (COALESCE(pgt.descricao_especificacao,'$title_specification')) specification_template_description"
                        . " FROM " . DB_PREFIX . "product p"
                        . " LEFT JOIN " . DB_PREFIX . "product_description   pd  ON (p.product_id = pd.product_id)"
                        . " LEFT JOIN " . DB_PREFIX . "product_kit pkit on pkit.product_id = p.product_id and pkit.site_utiliza='S'";

                    $sql .= isset($data_language) ? "LEFT JOIN " . DB_PREFIX . "product_translate pt ON (p.product_id = pt.product_id and pt.linguagem = '" . $data_language . "')" : "";

                    $sql .= " LEFT JOIN " . DB_PREFIX . "product_color         pc  ON (pc.productcolor_id = p.product_color_id)"
                        . " LEFT JOIN " . DB_PREFIX . "product_size          ps  ON (ps.productsize_id = p.product_size_id)"
                        . " LEFT JOIN " . DB_PREFIX . "product_specification psp ON (psp.productspecification_id = p.product_specification_id)"
                        . " LEFT JOIN oc_product_grid_detail pgd ON pgd.product_id = p.product_id"
                        . " LEFT JOIN oc_product_grid pg ON pg.product_grid_id = pgd.product_grid_id"
                        . " LEFT JOIN oc_product_grid_template pgt ON pg.product_grid_template_id = pgt.product_grid_template_id"
                        . " WHERE p.product_id = '" . (int)$product_id . "' AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.date_available <= NOW() AND p.status = '1'";
                } else {
                    $sql = "SELECT p.*, pd.*, pkit.product_kit_id AS product_kit_id ";
                    $sql .= isset($data_language) ? ",coalesce(pt.descricao_ecommerce, pd.name) as name, pt.linguagem, pt.descricao, pt.descricao_ecommerce, pt.descricao_completa, pt.descricao_completa_sf" : "";
                    $sql .= " FROM " . DB_PREFIX . "product p";
                    $sql .= " LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id)";
                    $sql .= " LEFT JOIN " . DB_PREFIX . "product_kit pkit on pkit.product_id = p.product_id and pkit.site_utiliza='S' ";
                    $sql .= isset($data_language) ? " LEFT JOIN oc_product_translate pt ON (p.product_id = pt.product_id and pt.linguagem = '" . $data_language . "')" : "";
                    $sql .= " WHERE p.product_id = '" . (int)$product_id . "' AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.date_available <= NOW() AND p.status = '1'";
                }

                $product_query = $this->db->query($sql);

                if ($product_query->num_rows) {
                    $option_price = 0;
                    $option_points = 0;
                    $option_weight = 0;

                    $option_data = array();

                    foreach ($options as $product_option_id => $option_value) {
                        $option_query = $this->db->query("SELECT po.product_option_id, po.option_id, od.name, o.type FROM " . DB_PREFIX . "product_option po LEFT JOIN `" . DB_PREFIX . "option` o ON (po.option_id = o.option_id) LEFT JOIN " . DB_PREFIX . "option_description od ON (o.option_id = od.option_id) WHERE po.product_option_id = '" . (int)$product_option_id . "' AND po.product_id = '" . (int)$product_id . "' AND od.language_id = '" . (int)$this->config->get('config_language_id') . "'");

                        if ($option_query->num_rows) {
                            if ($option_query->row['type'] == 'select' || $option_query->row['type'] == 'radio' || $option_query->row['type'] == 'image') {
                                $option_value_query = $this->db->query("SELECT pov.option_value_id, ovd.name, pov.quantity, pov.subtract, pov.price, pov.price_prefix, pov.points, pov.points_prefix, pov.weight, pov.weight_prefix FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_option_value_id = '" . (int)$option_value . "' AND pov.product_option_id = '" . (int)$product_option_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "'");

                                if ($option_value_query->num_rows) {
                                    if ($option_value_query->row['price_prefix'] == '+') {
                                        $option_price += $option_value_query->row['price'];
                                    } elseif ($option_value_query->row['price_prefix'] == '-') {
                                        $option_price -= $option_value_query->row['price'];
                                    }

                                    if ($option_value_query->row['points_prefix'] == '+') {
                                        $option_points += $option_value_query->row['points'];
                                    } elseif ($option_value_query->row['points_prefix'] == '-') {
                                        $option_points -= $option_value_query->row['points'];
                                    }

                                    if ($option_value_query->row['weight_prefix'] == '+') {
                                        $option_weight += $option_value_query->row['weight'];
                                    } elseif ($option_value_query->row['weight_prefix'] == '-') {
                                        $option_weight -= $option_value_query->row['weight'];
                                    }

                                    if ($option_value_query->row['subtract'] && (!$option_value_query->row['quantity'] || ($option_value_query->row['quantity'] < $quantity))) {
                                        $stock = false;
                                    }

                                    $option_data[] = array(
                                        'product_option_id'       => $product_option_id,
                                        'product_option_value_id' => $option_value,
                                        'option_id'               => $option_query->row['option_id'],
                                        'option_value_id'         => $option_value_query->row['option_value_id'],
                                        'name'                    => $option_query->row['name'],
                                        'option_value'            => $option_value_query->row['name'],
                                        'type'                    => $option_query->row['type'],
                                        'quantity'                => $option_value_query->row['quantity'],
                                        'subtract'                => $option_value_query->row['subtract'],
                                        'price'                   => $option_value_query->row['price'],
                                        'price_prefix'            => $option_value_query->row['price_prefix'],
                                        'points'                  => $option_value_query->row['points'],
                                        'points_prefix'           => $option_value_query->row['points_prefix'],
                                        'weight'                  => $option_value_query->row['weight'],
                                        'weight_prefix'           => $option_value_query->row['weight_prefix']
                                    );
                                }
                            } elseif ($option_query->row['type'] == 'checkbox' && is_array($option_value)) {
                                foreach ($option_value as $product_option_value_id) {
                                    $option_value_query = $this->db->query("SELECT pov.option_value_id, ovd.name, pov.quantity, pov.subtract, pov.price, pov.price_prefix, pov.points, pov.points_prefix, pov.weight, pov.weight_prefix FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_option_value_id = '" . (int)$product_option_value_id . "' AND pov.product_option_id = '" . (int)$product_option_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "'");

                                    if ($option_value_query->num_rows) {
                                        if ($option_value_query->row['price_prefix'] == '+') {
                                            $option_price += $option_value_query->row['price'];
                                        } elseif ($option_value_query->row['price_prefix'] == '-') {
                                            $option_price -= $option_value_query->row['price'];
                                        }

                                        if ($option_value_query->row['points_prefix'] == '+') {
                                            $option_points += $option_value_query->row['points'];
                                        } elseif ($option_value_query->row['points_prefix'] == '-') {
                                            $option_points -= $option_value_query->row['points'];
                                        }

                                        if ($option_value_query->row['weight_prefix'] == '+') {
                                            $option_weight += $option_value_query->row['weight'];
                                        } elseif ($option_value_query->row['weight_prefix'] == '-') {
                                            $option_weight -= $option_value_query->row['weight'];
                                        }

                                        if ($option_value_query->row['subtract'] && (!$option_value_query->row['quantity'] || ($option_value_query->row['quantity'] < $quantity))) {
                                            $stock = false;
                                        }

                                        $option_data[] = array(
                                            'product_option_id'       => $product_option_id,
                                            'product_option_value_id' => $product_option_value_id,
                                            'option_id'               => $option_query->row['option_id'],
                                            'option_value_id'         => $option_value_query->row['option_value_id'],
                                            'name'                    => $option_query->row['name'],
                                            'option_value'            => $option_value_query->row['name'],
                                            'type'                    => $option_query->row['type'],
                                            'quantity'                => $option_value_query->row['quantity'],
                                            'subtract'                => $option_value_query->row['subtract'],
                                            'price'                   => $option_value_query->row['price'],
                                            'price_prefix'            => $option_value_query->row['price_prefix'],
                                            'points'                  => $option_value_query->row['points'],
                                            'points_prefix'           => $option_value_query->row['points_prefix'],
                                            'weight'                  => $option_value_query->row['weight'],
                                            'weight_prefix'           => $option_value_query->row['weight_prefix']
                                        );
                                    }
                                }
                            } elseif ($option_query->row['type'] == 'text' || $option_query->row['type'] == 'textarea' || $option_query->row['type'] == 'file' || $option_query->row['type'] == 'date' || $option_query->row['type'] == 'datetime' || $option_query->row['type'] == 'time') {
                                $option_data[] = array(
                                    'product_option_id'       => $product_option_id,
                                    'product_option_value_id' => '',
                                    'option_id'               => $option_query->row['option_id'],
                                    'option_value_id'         => '',
                                    'name'                    => $option_query->row['name'],
                                    'option_value'            => $option_value,
                                    'type'                    => $option_query->row['type'],
                                    'quantity'                => '',
                                    'subtract'                => '',
                                    'price'                   => '',
                                    'price_prefix'            => '',
                                    'points'                  => '',
                                    'points_prefix'           => '',
                                    'weight'                  => '',
                                    'weight_prefix'           => ''
                                );
                            }
                        }
                    }

                    if (isset($product_session_cart['id_tabela_preco_ecommerce']) && $product_session_cart['id_tabela_preco_ecommerce'] > 0) {
                        $customer_group_id = $product_session_cart['id_tabela_preco_ecommerce'];
                    } else	if ($this->customer->isLogged()) {
                        $customer_group_id = $this->customer->getCustomerGroupId();
                    } else {
                        $customer_group_id = $this->config->get('config_customer_group_id');
                    }

                    $price = $product_query->row['price'];

                    // Product Discounts
                    $discount_quantity = 0;

                    foreach ($this->session->data['cart'] as $key_2 => $product_session_cart_2) {
                        $product_2 = explode(':', $key_2);

                        if ($product_2[0] == $product_id) {
                            $discount_quantity += (int)$product_session_cart_2['quantity'];
                        }
                    }

                    $product_discount_query = $this->db->query("SELECT price FROM " . DB_PREFIX . "product_discount WHERE product_id = '" . (int)$product_id . "' AND customer_group_id = '" . (int)$customer_group_id . "' AND quantity <= '" . (int)$discount_quantity . "' AND (quantity <> 0) AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW())) ORDER BY quantity DESC, priority ASC, price ASC LIMIT 1");

                    if ($product_discount_query->num_rows) {
                        $price = $product_discount_query->row['price'];
                    }

                    $product_special_query = $this->db->query("select coalesce(perc_discount, 0) perc_discount from " . DB_PREFIX . "order_discount  where (product_id = '" . (int)$product_id . "') and (tipo_promocao = " . Type_Promocao::Tp_PercDesconto . ") and (status = " . Type_PromocaoStatus::Tp_Ativo  . ") and ((date_start = '0000-00-00') or (date_start <= CURDATE())) and ((date_end = '0000-00-00') or (date_end >= CURDATE())) ORDER BY perc_discount DESC LIMIT 1");

                    //Validação para o desconto da lista escolar
                    $desconto_lista = 0;
                    if ($this->config->get('listaescolar_status') && $lista_escolar_id > 0) {
                        $this->load->dmodel('listaescolar/listaescolar');
                        $perc_desconto_lista = $this->dmodel_listaescolar_listaescolar->getDescontoLista($product_query->row['product_id'], $lista_escolar_id);
                        $desconto_lista =  (((float)$perc_desconto_lista * 0.01) * $price);
                    }
                    //Validação para o desconto da lista escolar

                    //Recebe valor original do produto sem desconto.
                    $price_not_discount = $price;
                    $auto_discount = 0;
                    $auto_perc = 0;
                    if (($product_special_query->num_rows) && ($product_special_query->row['perc_discount'] > 0)) {
                        $auto_perc = $product_special_query->row['perc_discount'];
                        $auto_discount = ($auto_perc * 0.01) * $price;
                        $price = $price - $auto_discount;
                    }

                    //Valor do produto com desconto.
                    $price = $price - $desconto_lista;

                    // Reward Points
                    $product_reward_query = $this->db->query("SELECT points FROM " . DB_PREFIX . "product_reward WHERE product_id = '" . (int)$product_id . "' AND customer_group_id = '" . (int)$customer_group_id . "'");

                    if ($product_reward_query->num_rows) {
                        $reward = $product_reward_query->row['points'];
                    } else {
                        $reward = 0;
                    }

                    // Stock
                    if (!$product_query->row['quantity'] || ($product_query->row['quantity'] < $quantity)) {
                        $stock = false;
                    }

                    $recurring = false;
                    $recurring_frequency = 0;
                    $recurring_price = 0;
                    $recurring_cycle = 0;
                    $recurring_duration = 0;
                    $recurring_trial_status = 0;
                    $recurring_trial_price = 0;
                    $recurring_trial_cycle = 0;
                    $recurring_trial_duration = 0;
                    $recurring_trial_frequency = 0;
                    $profile_name = '';

                    if ($profile_id) {
                        $profile_info = $this->db->query("SELECT * FROM `" . DB_PREFIX . "profile` `p` JOIN `" . DB_PREFIX . "product_profile` `pp` ON `pp`.`profile_id` = `p`.`profile_id` AND `pp`.`product_id` = " . (int) $product_query->row['product_id'] . " JOIN `" . DB_PREFIX . "profile_description` `pd` ON `pd`.`profile_id` = `p`.`profile_id` AND `pd`.`language_id` = " . (int) $this->config->get('config_language_id') . " WHERE `pp`.`profile_id` = " . (int) $profile_id . " AND `status` = 1 AND `pp`.`customer_group_id` = " . (int) $customer_group_id)->row;

                        if ($profile_info) {
                            $profile_name = $profile_info['name'];

                            $recurring = true;
                            $recurring_frequency = $profile_info['frequency'];
                            $recurring_price = $profile_info['price'];
                            $recurring_cycle = $profile_info['cycle'];
                            $recurring_duration = $profile_info['duration'];
                            $recurring_trial_frequency = $profile_info['trial_frequency'];
                            $recurring_trial_status = $profile_info['trial_status'];
                            $recurring_trial_price = $profile_info['trial_price'];
                            $recurring_trial_cycle = $profile_info['trial_cycle'];
                            $recurring_trial_duration = $profile_info['trial_duration'];
                        }
                    }

                    $type = ftr_geral::isIsset($this->config->get('config_product_code')) ? $this->config->get('config_product_code') : Type_ListCodProduct::Tp_CodReferencia;
                    switch ($type) {
                        case Type_ListCodProduct::Tp_CodReferencia:
                            $model = $product_query->row['model'];
                            break;
                        case Type_ListCodProduct::Tp_CodProdEcommerce:
                            $model = $product_query->row['product_id'];
                            break;
                        case Type_ListCodProduct::Tp_CodProdFuturaServer:
                            $model = $product_query->row['id_futura'];
                            break;
                        case Type_ListCodProduct::Tp_CodBarras:
                            $model = $product_query->row['codigo_barra'];
                            break;
                        default:
                            $model = $product_query->row['model'];
                    }

                    if ($this->config->get('futuragrade_status') && in_array($product_query->row['tipo'], [Type_ProdutoGrade::Tp_MercadoriaRevenda, Type_ProdutoGrade::Tp_ProdutoAcabado])) {
                        $this->load->model('catalog/product');
                        $gridhave = $this->model_catalog_product->getGridHave($product_id);
                        $gridhaveid = ($gridhave['grid_id']) ? $gridhave['grid_id'] : false;
                    } else {
                        $gridhaveid = false;
                    }

                    $this->data[$key] = array(
                        'grid_id'                   => $gridhaveid,
                        'key'                       => $key,
                        'product_id'                => $product_query->row['product_id'],
                        'description'                => $product_query->row['description'],
                        'ipi_valor'                 => 'N', //inicialmente com valor zerado, precisa calcular
                        'st_valor'                  => 'N', //inicialmente com valor zerado, precisa calcular
                        'fcpst_valor'               => 'N', //inicialmente com valor zerado, precisa calcular
                        'st_base'                   => 'N',
                        'fcpst_base'                => 'N',
                        'ipi_percentual'            => 'N',
                        'desconto_valor'            => $auto_discount * $quantity,
                        'desconto_automatico'       => $auto_discount * -1,
                        'acrescimo_valor'           => 0,
                        'frete_valor'               => 0,
                        'desconto_percentual'       => $auto_perc,
                        'acrescimo_percentual'      => 0,
                        'acerto_kit'                => 0,
                        'acerto_kit_desconto'       => 0,
                        'acerto_kit_acrescimo'      => 0,
                        'price_kit'                 => 0,
                        'total_kit'                 => 0,
                        'id_futura'                 => $product_query->row['id_futura'],
                        'name'                      => $product_query->row['name'],
                        'model'                     => $model,
                        'shipping'                  => $product_query->row['shipping'],
                        'image'                     => $product_query->row['image'],
                        'data_atualizacao_replicacao' => $product_query->row['data_atualizacao_replicacao'],
                        'option'                    => $option_data,
                        'quantity'                  => $quantity,
                        'fator_multiplicador'       => ($this->config->get('config_fator_multiplicador') && ((int)$product_query->row['quantity_unit'] != 0)) ? (int)$product_query->row['quantity_unit'] : 1,
                        'minimum'                   => $product_query->row['minimum'],
                        'subtract'                  => $product_query->row['subtract'],
                        'stock'                     => $stock,
                        'color_description'         => ($this->config->get('futuragrade_status')) ? $product_query->row['color_description'] : '',
                        'size_description'          => ($this->config->get('futuragrade_status')) ? $product_query->row['size_description']  : '',
                        'specification_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['specification_description'] : '',
                        'color_template_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['color_template_description'] : '',
                        'size_template_description'  => ($this->config->get('futuragrade_status')) ? $product_query->row['size_template_description']  : '',
                        'specification_template_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['specification_template_description'] : '',
                        'price_not_discount'        => $price_not_discount,
                        'price'                     => ($price + $option_price),
                        'sub_total'                 => $price_not_discount * (int)$quantity,
                        'total'                     => ($price + $option_price) * (int)$quantity,
                        'reward'                    => $reward * (int)$quantity,
                        'points'                    => ($product_query->row['points'] ? ($product_query->row['points'] + $option_points) * $quantity : 0),
                        'weight'                    => ($product_query->row['weight'] + $option_weight) * (int)$quantity,
                        'net_weight'                => $product_query->row['net_weight'] * (int)$quantity,
                        'weight_class_id'           => $product_query->row['weight_class_id'],
                        'weight_unit'               => $product_query->row['weight'],
                        'net_weight_unit'           => $product_query->row['net_weight'],
                        'length'                    => $product_query->row['length'],
                        'width'                     => $product_query->row['width'],
                        'height'                    => $product_query->row['height'],
                        'comp_progressiva'          => $product_query->row['comp_progressiva'],
                        'larg_progressiva'          => $product_query->row['larg_progressiva'],
                        'alt_progressiva'           => $product_query->row['alt_progressiva'],
                        'length_class_id'           => $product_query->row['length_class_id'],
                        'profile_id'                => $profile_id,
                        'profile_name'              => $profile_name,
                        'recurring'                 => $recurring,
                        'recurring_frequency'       => $recurring_frequency,
                        'recurring_price'           => $recurring_price,
                        'recurring_cycle'           => $recurring_cycle,
                        'recurring_duration'        => $recurring_duration,
                        'recurring_trial'           => $recurring_trial_status,
                        'recurring_trial_frequency' => $recurring_trial_frequency,
                        'recurring_trial_price'     => $recurring_trial_price,
                        'recurring_trial_cycle'     => $recurring_trial_cycle,
                        'recurring_trial_duration'  => $recurring_trial_duration,
                        'sku'                       => $product_query->row['sku'],
                        'lista_escolar_id'          => $lista_escolar_id,
                        'lista_escolar_descricao'   => isset($product_session_cart['listaescolar_descricao']) ? $product_session_cart['listaescolar_descricao'] : null,
                        'lista_escolar_escola'      => isset($product_session_cart['listaescolar_escola']) ? $product_session_cart['listaescolar_escola'] : null,
                        'lista_escolar_serie'       => isset($product_session_cart['listaescolar_serie']) ? $product_session_cart['listaescolar_serie'] : null,
                        'observation'               => isset($product_session_cart['observation']) ? $product_session_cart['observation'] : null,
                        'product_kit_id'            => $product_query->row['product_kit_id'],
                        'itens_kit'                 => array()
                    );
                    if($this->data[$key]['product_kit_id']){
                        $this->load->dmodel('catalog/product');
                        $this->data[$key]['itens_kit'] = $this->dmodel_catalog_product->getProductKitItens($product_query->row['product_kit_id']);
                    }
                } else {
                    $this->remove($key);
                }
            }

            if ( isset($this->data) && count($this->data)>0 ){
                $rate = $this->rateiaValores();
            }
        }

        try {
            $modulostconf = $this->futuracalcularst->getconfiguracoes();
            if (!empty($modulostconf)&&$rate) {
                if (($this->customer->isLogged()) && ($this->customer->getTipo_pessoa() == 'J') && ($modulostconf['futuracalcularst_status']) && ($this->flag)) {
                    $this->flag = false;
                    $productCalc = null;
                    $this->load->dmodel('catalog/product');
                    $sequencia = 0; //tem que ser assim e não o incremental do for por causa do kit

                    foreach ($this->data as $product) {
                        $acerto_total = 0;
                        $total_kit = 0;
                        $acerto_desconto = 0;
                        $acerto_acrescimo = 0;
                        if ($product['product_kit_id']) {
                            //$itens_kit = $this->dmodel_catalog_product->getProductKitItens($product['product_kit_id']);
                            foreach ($product['itens_kit'] as $product_kit) {
                                $sequencia = $sequencia += 1;
                                $productCalc[] = array(
                                    'id_futura' => $product_kit['product_id_futura'],
                                    'quantity'  => (int)$product_kit['quantidade'] * $product['quantity'],
                                    'price'     => (float)$product_kit['price'],
                                    'total'     => (float)$product_kit['price'] * ((int)$product_kit['quantidade'] * (int)$product['quantity']),
                                    'product_kit_id' => (int)$product['product_kit_id'],
                                    'id_pkit_futura' => (int)$product['id_futura'], /* ID futura do produto pai (KIT) */
                                    'sequencia'      => $sequencia,
                                    'acerto' => (float)$product_kit['acerto'] * $product['quantity'],
                                    'desconto_valor'  => isset($product_kit['desconto_valor']) ? $product_kit['desconto_valor'] : 0,
                                    'acrescimo_valor' => isset($product_kit['acrescimo_valor']) ?$product_kit['acrescimo_valor'] :0 ,
                                    'frete_valor'     => isset($product_kit['frete_valor']) ? $product_kit['frete_valor'] : 0,
                                    'acrescimo_percentual' => isset($product_kit['acrescimo_percentual']) ? $product_kit['acrescimo_percentual'] : 0,
                                    'desconto_percentual'  => isset($product_kit['desconto_percentual']) ? $product_kit['desconto_percentual'] : 0,
                                    'sequence_kit_key'     => isset($product_kit['sequence_key']) ? $product_kit['sequence_key'] : 0
                                );
                                $acerto_total += (float)$product_kit['acerto'] * $product['quantity'] ;
                                if ((float)$product_kit['acerto'] > 0){
                                    $acerto_acrescimo += (float)$product_kit['acerto'] * (int)$product['quantity'];
                                }else{
                                    $acerto_desconto += (float)$product_kit['acerto'] * (int)$product['quantity'];
                                }
                                $total_kit += (float)$product_kit['total'] * $product['quantity'];
                            }

                            $this->data[$product['key']]['total_kit']  = $total_kit;
                            $this->data[$product['key']]['acerto_kit'] = $acerto_total;
                            $this->data[$product['key']]['acerto_kit_desconto']  = $acerto_desconto;
                            $this->data[$product['key']]['acerto_kit_acrescimo'] = $acerto_acrescimo;
                        } else {
                            $sequencia = $sequencia += 1;
                            $productCalc[] = array(
                                'id_futura' => $product['id_futura'],
                                'quantity'  => $product['quantity'],
                                'price'     => $product['price'],
                                'total'     => $product['total'],
                                'cart_key'  => $product['key'],
                                'desconto_valor'  => isset($product['desconto_valor']) ? $product['desconto_valor'] : 0,
                                'acrescimo_valor' => isset($product['acrescimo_valor']) ?$product['acrescimo_valor'] :0 ,
                                'frete_valor'     => isset($product['frete_valor']) ? $product['frete_valor'] : 0,
                                'acrescimo_percentual' => isset($product['acrescimo_percentual']) ? $product['acrescimo_percentual'] : 0,
                                'desconto_percentual'  => isset($product['desconto_percentual']) ? $product['desconto_percentual'] : 0,
                                'sequencia' => $sequencia,
                                'acerto' => 0
                            );
                        }
                    }

                    $prodslist        = $this->futuracalcularst->getJsonCalculaST($productCalc, $this->customer->getID_Futura());

                    if ($prodslist) {
                        foreach ($this->data as $produto) {
                            $this->data[$produto['key']]['st_valor']       = $prodslist[$this->data[$produto['key']]['id_futura']]['SubstTribValor'];
                            $this->data[$produto['key']]['ipi_valor']      = $prodslist[$this->data[$produto['key']]['id_futura']]['IPIValor'];
                            $this->data[$produto['key']]['fcpst_valor']    = $prodslist[$this->data[$produto['key']]['id_futura']]['FcpSubstTribValor'];

                            $this->data[$produto['key']]['st_base']        = $prodslist[$this->data[$produto['key']]['id_futura']]['SubstTribBase'];
                            $this->data[$produto['key']]['fcpst_base']     = $prodslist[$this->data[$produto['key']]['id_futura']]['FcpSubstTribBase'];
                            $this->data[$produto['key']]['ipi_percentual'] = $prodslist[$this->data[$produto['key']]['id_futura']]['IPIAliquota'];

                            if (isset($prodslist[$this->data[$produto['key']]['id_futura']]['itens_kit'])) {
                                $this->data[$produto['key']]['itens_kit']  = $prodslist[$this->data[$produto['key']]['id_futura']]['itens_kit'];
                            }
                        }
                    } else {
                        foreach ($this->data as $produto) {
                            $this->data[$produto['key']]['st_valor']       = 'N';
                            $this->data[$produto['key']]['ipi_valor']      = 'N';
                            $this->data[$produto['key']]['fcpst_valor']    = 'N';
                            $this->data[$produto['key']]['st_base']        = 'N';
                            $this->data[$produto['key']]['fcpst_base']     = 'N';
                            $this->data[$produto['key']]['ipi_percentual'] = 'N';
                        }
                    }

                    $this->flag = true;
                }
            }
        } catch (Exception $e) {
            $this->flag = true;
            throw $e;
        }

        return $this->data;
    }

    public function getRecurringProducts()
    {
        $recurring_products = array();

        foreach ($this->getProducts() as $key => $value) {
            if ($value['recurring']) {
                $recurring_products[$key] = $value;
            }
        }

        return $recurring_products;
    }

    public function add($product_id, $qty = 1, $option = '', $profile_id = '')
    {
        $key = (int) $product_id . ':';

        if ($option) {
            $key .= base64_encode(serialize($option)) . ':';
        } else {
            $key .= ':';
        }

        if ($profile_id) {
            $key .= (int) $profile_id;
        }

        if ((int) $qty && ((int) $qty > 0)) {
            if (!isset($this->session->data['cart'][$key])) {
                $this->session->data['cart'][$key] =
                    array(
                        'quantity' => (int) $qty
                    );
            } else {
                $this->session->data['cart'][$key]['quantity'] += (int) $qty;
            }
        }

        $this->data = array();
    }



    public function addQtd($grid_id, $qty = 1)
    {
        $key = (int) $grid_id;
        if (!array_key_exists($grid_id, $this->session->data['addQtd'])) {
            $this->session->data['addQtd'] = array();
            $this->session->data['addQtd'][$key] = (int) $qty;
        } else {
            $this->session->data['addQtd'][$key] = (int) $qty;
        }

        $this->data = array();
    }


    public function update($key, $qty)
    {
        if ((int)$qty && ((int)$qty > 0)) {
            $this->session->data['cart'][$key]['quantity'] = (int)$qty;
        } else {
            $this->remove($key);
        }

        $this->data = array();
    }

    public function remove($key)
    {
        if (isset($this->session->data['cart'][$key])) {
            unset($this->session->data['cart'][$key]);
        }

        $this->data = array();
    }

    public function clear()
    {
        $this->session->data['cart'] = array();

        $this->session->data['addQtd'] = array();

        $this->data = array();
    }

    public function getWeight()
    {
        $weight = 0;

        foreach ($this->getProducts() as $product) {
            if ($product['shipping']) {
                $weight += $this->weight->convert($product['weight'], $product['weight_class_id'], $this->config->get('select_peso'));
            }
        }

        return $weight;
    }

    public function getNetWeight()
    {
        $weight = 0;

        foreach ($this->getProducts() as $product) {
            if ($product['shipping']) {
                $weight += $this->weight->convert($product['net_weight'], $product['weight_class_id'], $this->config->get('select_peso'));
            }
        }

        return $weight;
    }

    public function getSubTotal()
    {
        $total = 0;

        foreach ($this->getProducts() as $product) {
            if ($product['total_kit'] > 0) {
                $total += $product['total_kit'];
            } else {
                $total += $product['sub_total'];
            }
        }

        return $total;
    }

    public function getTaxesST()
    {
        $tax_total = 0;
        if ($this->config->get('futuracalcularst_status')) {
            foreach ($this->getProducts() as $product) {
                if (is_numeric($product['ipi_valor']) && is_numeric($product['st_valor']) && is_numeric($product['fcpst_valor'])) {
                    $tax_total += $product['ipi_valor'] + $product['st_valor'] + $product['fcpst_valor'];
                }
            }
        }
        return $tax_total;
    }

    public function getTotal()
    {
        $total = 0;

        foreach ($this->getProducts() as $product) {
            $total += $product['price'] * $product['quantity'];
        }

        return $total;
    }

    public function getTotalSemFrete()
    {
        $this->load->model('setting/extension');

        $total_data = array();
        $total = 0;
        $sort_order = array();
        $results = $this->model_setting_extension->getExtensions('total');
        foreach ($results as $key => $value) {
            $sort_order[$key] = $this->config->get($value['code'] . '_sort_order');
        }
        array_multisort($sort_order, SORT_ASC, $results);

        foreach ($results as $result) {
            if ($this->config->get($result['code'] . '_status')  && $result['code'] == 'coupon') {
                $this->load->model('total/' . $result['code']);
                $this->{'model_total_' . $result['code']}->getTotal($total_data, $total, false);
            } else if ($this->config->get($result['code'] . '_status')  && $result['code'] <> 'shipping') {
                $this->load->model('total/' . $result['code']);
                $this->{'model_total_' . $result['code']}->getTotal($total_data, $total);
            }

            $sort_order = array();
            foreach ($total_data as $key => $value) {
                $sort_order[$key] = $value['sort_order'];
            }
            array_multisort($sort_order, SORT_ASC, $total_data);
        }

        foreach ($total_data as $total_total) {
            if ($total_total['code'] == 'total' || $total_total['code'] == 'sub_total') {
                return $total_total['value'];
            }
        }
    }

    public function countProducts()
    {
        $product_total = 0;

        $products = $this->getProducts();

        foreach ($products as $product) {
            $product_total += (int)$product['quantity'];
        }

        return $product_total;
    }

    public function countVariedadeProducts($idProduto = 0)
    {
        //O $idProduto serve para verificar se já existe o produto na lista
        //Caso ele não exista soma mais um no retorno pois o produto está sendo adicionado.
        $product_total = 0;
        $products = $this->getProducts();

        if (count($products) > 0) {
            $produtoListado = false;
            foreach ($products as $product) {
                $product_total += 1;
                if ($product['product_id'] == $idProduto) {
                    $produtoListado = true;
                }
            }

            if ((!$produtoListado) && ($idProduto > 0)) {
                $product_total += 1;
            }
        }

        return $product_total;
    }


    public function hasProducts()
    {
        return count($this->session->data['cart']);
    }

    public function hasRecurringProducts()
    {
        return count($this->getRecurringProducts());
    }

    public function hasStock()
    {
        $stock = true;

        foreach ($this->getProducts() as $product) {
            if (!$product['stock']) {
                $stock = false;
            }
        }

        return $stock;
    }

    public function hasShipping()
    {
        $shipping = false;

        foreach ($this->getProducts() as $product) {
            if ($product['shipping']) {
                $shipping = true;

                break;
            }
        }

        return $shipping;
    }

    public function hasDownload()
    {
        $download = false;

        foreach ($this->getProducts() as $product) {
            if ($product['download']) {
                $download = true;

                break;
            }
        }

        return $download;
    }

    public function getItemQuantity($product_id)
    {
        return isset($this->getProducts()[$product_id . '::']['quantity']) ? $this->getProducts()[$product_id . '::']['quantity'] : 0;
    }

    public function isFatorMultiplicador($arrayFator = false)
    {
        if ($arrayFator) {
            foreach ($arrayFator as $key => $value) {
                $product = $this->getProducts()[key($arrayFator)];
                $status  = (($value % $product['fator_multiplicador']) == 0) ? true : false;
            }
            return ['status' => $status, 'fator' => $product['fator_multiplicador'], 'name' => $product['name']];
        } else {
            $retorno = false;
            foreach ($this->getProducts() as $key => $product) {
                $status  = (($product['quantity'] % $product['fator_multiplicador']) == 0) ? true : false;
                if (!$status) {
                    return ['status' => $status, 'fator' => $product['fator_multiplicador'], 'name' => $product['name']];
                }
            }
            return $retorno;
        }
    }

    public function hasGridId()
    {

        $grid_id = false;
        foreach ($this->getProducts() as $product) {
            if ($product['grid_id']) {
                $grid_id[] = $product['grid_id'];
            }
        }

        return $grid_id;
    }
}
